React Native之didFocus和didBlur
1 didFocus和didBlur解釋
didFocus - the screen focused (if there was a transition, the transition completed)
didBlur - the screen unfocused (if there was a transition, the transition completed)
didFocus是指當(dāng)前頁(yè)面第一次加載的時(shí)候會(huì)調(diào)用一次
didBlur是指當(dāng)前頁(yè)面離開(kāi)的時(shí)候會(huì)調(diào)用一次(前提是當(dāng)前頁(yè)面沒(méi)有被銷(xiāo)毀既沒(méi)有執(zhí)行componentWillUnmount()函數(shù))
2 測(cè)試代碼
import React from 'react';
import { View, Text, Button} from 'react-native';
import { createStackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
constructor(props) {
super(props);
console.log("HomeScreen constructor start");
this.didFocusListener = this.props.navigation.addListener(
'didFocus',
(obj) => {console.log("HomeScreen didFocus start")}
);
this.didBlurListener = this.props.navigation.addListener(
'didBlur',
(obj) => {console.log('HomeScreen didBlur start')}
);
}
static navigationOptions = {
title : 'HomeScreen',
}
componentDidMount = () => {
console.log("HomeScreen componentDidMount start")
}
componentWillUnmount() {
console.log("HomeScreen componentWillUnmount start")
this.didFocusListener.remove();
this.didBlurListener.remove();
}
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home Screen</Text>
<Button onPress={() => this.props.navigation.navigate('Details', {
itemId:100,
otherParam:'chenyu',
})} title = "go to Details"/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
class DetailsScreen extends React.Component {
constructor(props) {
super(props);
console.log("DetailsScreen constructor start");
this.didFocusListener = this.props.navigation.addListener(
'didFocus',
(obj) => {console.log("DetailsScreen didFocus start")}
);
this.didBlurListener = this.props.navigation.addListener(
'didBlur',
(obj) => {console.log('DetailsScreen didBlur start')}
);
}
static navigationOptions = ({navigation}) => {
return {
title : navigation.getParam('otherParam', 'no-values'),
};
};
componentDidMount = () => {
console.log("DetailsScreen componentDidMount start")
}
componentWillUnmount() {
console.log("DetailsScreen componentWillUnmount start")
this.didFocusListener.remove();
this.didBlurListener.remove();
}
render() {
const {navigation} = this.props;
const itemId = navigation.getParam('itemId', 'no-values');
const otherParam = navigation.getParam('otherParam', 'no-values');
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>itemId:{JSON.stringify(itemId)}</Text>
<Text>otherParam:{JSON.stringify(otherParam)}</Text>
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.push('Details', {
itemId: Math.floor(Math.random() * 100),
})}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
<Button
title="Go popToTop"
onPress={() => this.props.navigation.popToTop()}
/>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return <RootStack/>;
}
}
3 運(yùn)行結(jié)果
2個(gè)頁(yè)面分別如下
在控制臺(tái)過(guò)來(lái)React Native命令
adb logcat | grep ReactNativeJS
1) 程序起來(lái)打印日志如下
I/ReactNativeJS(21233): HomeScreen constructor start
I/ReactNativeJS(21233): HomeScreen componentDidMount start
I/ReactNativeJS(21233): HomeScreen didFocus start
這里的didFocus start是在componentDidMount后面執(zhí)行
2 ) 然后點(diǎn)擊go to DETAILS按鈕日志如下
I/ReactNativeJS(21233): DetailsScreen constructor start
I/ReactNativeJS(21233): DetailsScreen componentDidMount start
I/ReactNativeJS(21233): HomeScreen didBlur start
I/ReactNativeJS(21233): DetailsScreen didFocus start
然后執(zhí)行了HomeScreen didBlur start,但是并沒(méi)有執(zhí)行HomeScreen componentWillUnmount start,因?yàn)轫?yè)面還沒(méi)有銷(xiāo)毀,所以執(zhí)行了HomeScreen didBlur start.
3 )然后在在第二個(gè)頁(yè)面點(diǎn)擊"GO BACK"或者按下返回鍵,日志打印如下
I/ReactNativeJS(21233): DetailsScreen componentWillUnmount start
I/ReactNativeJS(21233): HomeScreen didFocus start
發(fā)現(xiàn)沒(méi)有,既然執(zhí)行了componentWillUnmount函數(shù),說(shuō)明頁(yè)面已經(jīng)銷(xiāo)毀,既然銷(xiāo)毀了,就沒(méi)有執(zhí)行DetailsScreen didBlur start,因?yàn)榍懊娴捻?yè)面沒(méi)有死,所以不會(huì)重新加載再次調(diào)用首頁(yè)的constructor和componentDidMount方法.從前面日志打印
I/ReactNativeJS(21233): DetailsScreen constructor start
I/ReactNativeJS(21233): DetailsScreen componentDidMount start
I/ReactNativeJS(21233): HomeScreen didBlur start
I/ReactNativeJS(21233): DetailsScreen didFocus start
可以看出,另外一個(gè)頁(yè)面執(zhí)行新頁(yè)面的constructor函數(shù)和componentDidMount函數(shù)才執(zhí)行之前頁(yè)面的didBlur start,所以估計(jì)這里是來(lái)不及執(zhí)行頁(yè)面就銷(xiāo)毀了,所以沒(méi)有打印DetailsScreen didBlur start.
4 )然后再次點(diǎn)擊返回物理鍵日志如下
I/ReactNativeJS(23183): HomeScreen componentWillUnmount start
只調(diào)用了componentWillUnmount函數(shù),所以頁(yè)面銷(xiāo)毀了,HomeScreen didBlur start來(lái)不及打印.
4 總結(jié)
didFocus只會(huì)在當(dāng)前頁(yè)面的constructor函數(shù)和componentDidMount函數(shù)后面執(zhí)行
didBlur只會(huì)在當(dāng)前頁(yè)面沒(méi)有調(diào)用componentWillUnmount函數(shù),然后離開(kāi)當(dāng)前頁(yè)面才執(zhí)行,也意味著,這個(gè)頁(yè)面沒(méi)有死但是去了另外一個(gè)頁(yè)面才會(huì)調(diào)用,如果自己頁(yè)面死了,就不會(huì)調(diào)用到這里.
作者:chen.yu
深信服三年半工作經(jīng)驗(yàn),目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號(hào):編程入門(mén)到禿頭 或掃描下面二維碼
零基礎(chǔ)入門(mén)進(jìn)階人工智能(鏈接)