didFocus and didBlur of React Native

Keywords: Mobile React JSON

1. didFocus and didBlur Explanations

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 means that the current page will be called once when it is first loaded.

didBlur is called once when the current page leaves (provided that the current page is not destroyed and that the componentWillUnmount() function is not executed)

 

 

2 test code

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 Running results

The two pages are as follows

 

 

 

React Native command from console

adb logcat | grep ReactNativeJS

1) Procedure to print the log as follows

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

Here didFocus start is executed after component DidMount

 

2) Then click the go to DETAILS button to log as follows

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

Then the HomeScreen didBlur start was executed, but the HomeScreen component WillUnmount start was not executed because the page was not destroyed, so the HomeScreen didBlur start was executed.

 

3) Then click "GO BACK" on the second page or press the return key. The log is printed as follows

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

No, since the componentWillUnmount function has been executed, indicating that the page has been destroyed, and since destroyed, no Details Screen didBlur start has been executed, because the previous page is not dead, so it will not reload the constructor and componentDidMount methods that call the home page again. Print from the previous log.

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

As you can see, the constructor function and component DidMount function of another page execute the didBlur start of the previous page, so it is estimated that the page is destroyed before it can be executed, so the Details Screen didBlur start is not printed.

4) Then click back to the physical key log as follows

I/ReactNativeJS(23183): HomeScreen componentWillUnmount start

Only the component WillUnmount function was called, so the page was destroyed and HomeScreen didBlur start was too late to print.

 

 

 

4 Summary

didFocus will only be executed after the constructor function and component DidMount function of the current page

didBlur only calls the component WillUnmount function on the current page and then executes after leaving the current page. It also means that the page is not dead but it is called on another page. If its own page is dead, it will not be called here.

 

 

Posted by Jarl on Mon, 28 Jan 2019 12:06:14 -0800