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是指当前页面第一次加载的时候会调用一次

didBlur是指当前页面离开的时候会调用一次(前提是当前页面没有被销毁既没有执行componentWillUnmount()函数)

 

 

2 测试代码

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,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 运行结果

2个页面分别如下

 

 

 

在控制台过来React Native命令

adb logcat | grep ReactNativeJS

1) 程序起来打印日志如下

I/ReactNativeJS(21233): HomeScreen constructor start
I/ReactNativeJS(21233): HomeScreen componentDidMount start
I/ReactNativeJS(21233): HomeScreen didFocus start

这里的didFocus start是在componentDidMount后面执行

 

2 ) 然后点击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

然后执行了HomeScreen didBlur start,但是并没有执行HomeScreen componentWillUnmount start,因为页面还没有销毁,所以执行了HomeScreen didBlur start.

 

3 )然后在在第二个页面点击"GO BACK"或者按下返回键,日志打印如下

I/ReactNativeJS(21233): DetailsScreen componentWillUnmount start
I/ReactNativeJS(21233): HomeScreen didFocus start

发现没有,既然执行了componentWillUnmount函数,说明页面已经销毁,既然销毁了,就没有执行DetailsScreen didBlur start,因为前面的页面没有死,所以不会重新加载再次调用首页的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

可以看出,另外一个页面执行新页面的constructor函数和componentDidMount函数才执行之前页面的didBlur start,所以估计这里是来不及执行页面就销毁了,所以没有打印DetailsScreen didBlur start.

4 )然后再次点击返回物理键日志如下

I/ReactNativeJS(23183): HomeScreen componentWillUnmount start

只调用了componentWillUnmount函数,所以页面销毁了,HomeScreen didBlur start来不及打印.

 

 

 

4 总结

didFocus只会在当前页面的constructor函数和componentDidMount函数后面执行

didBlur只会在当前页面没有调用componentWillUnmount函数,然后离开当前页面才执行,也意味着,这个页面没有死但是去了另外一个页面才会调用,如果自己页面死了,就不会调用到这里.

 

 

相关文章

这篇文章主要讲解了“FlutterComponent动画的显和隐怎么实现...
这篇文章主要讲解了“flutter微信聊天输入框功能如何实现”,...
本篇内容介绍了“Flutter之Navigator的高级用法有哪些”的有...
这篇文章主要介绍“Flutter怎么使用Android原生播放器”,在...
Flutter开发的android端如何修改APP名称,logo,版本号,具体...
Flutter路由管理初识路由概念一.路由管理1.1.Route1.2.Mater...