rnn
rnn

Reputation: 2563

Why does componentWillUnmount() not working?

I want to remove event listener after navigate another screen however componentWillUnmount() not working ? I navigate like this:

this.props.navigation.navigate('newScreen')

after navigate I want to remove listener with componentWillUnmount

  componentDidMount() {
    this.backHandler = BackHandler.addEventListener(
      'hardwareBackPress',
      this.handleBackPress,
    );
  }

  componentWillUnmount() {
    console.warn('removed');
    this.backHandler.remove();
  }

  handleBackPress = () => {
    return true;
  };

Upvotes: 1

Views: 1084

Answers (1)

Auticcat
Auticcat

Reputation: 4489

As you're using a StackNavigator, the previous screen won't unmount if you do a navigate.

Take for example 3 screens inside a Stack :

Screen1 (initialRoute)

Screen2

Screen3

The moment you mount the StackNavigator, you'll have a Stack with one element.

Stack: Screen1

Navigating to another screen in a Stack, won't unmount the first screen, it will keep it active and push the next screen to the Stack.

So, doing. this.props.navigation.navigate("Screen2") will leave the Stack looking like:

Stack: Screen1 (unfocused), Screen2(focused).

If you push another screen to the Stack, it will keep all screens mounted.

this.props.navigation.navigate("Screen3")

Stack: Screen1 (unfocused), Screen2(unfocused), Screen3(focused).

The screens will only unmount (using navigate) if you navigate to an already mounted screen.

Doing:

this.props.navigation.navigate("Screen1")

will leave the Stack like:

Stack: Screen1

The solution for your problem would be to use the navigation HOC withNavigationFocus.

withNavigation focus will let you know when the screen is focused or not, and from that know do what you need. Your component would look like:

import { withNavigationFocus } from "react-navigation"

...

  componentDidMount() {
    this.backHandler = BackHandler.addEventListener(
      'hardwareBackPress',
      this.handleBackPress,
    );
  }

  componentDidUpdate(prevProps) {
    if(prevProps.isFocused !== this.props.isFocused)
      this.props.isFocused === true 
    ? this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
    : this.backHandler.remove();

  }

  componentWillUnmount() {
    console.warn('removed');
    this.backHandler.remove();
  }

  handleBackPress = () => {
    return true;
  };

...

export default withNavigationFocus(Component);

Upvotes: 2

Related Questions