2

Right now I have the following:

componentWillUnmount() { console.log("Leaving"); this._isMounted = false; }
componentDidMount() { this._isMounted = true; }

I have a function like so:

this.saveSomething(this.state.data).then((response) => {

  if(response !== null) {

    console.log(this._isMounted);

    if(this._isMounted) {
      Alert.alert(
        'Success!', 'It was saved',
        [
          {text: 'Go Home', style: 'cancel', onPress: () => {
            //navigate the app home
            this.props.navigation.navigate('Home');
          }},
          {text: 'Stay Here'},
          {text: 'Do something else', onPress: () => {
            //stuff that they need to be on the page to do
          }}
        ]
      );
    }
  }
})

If this functions runs and I click the back button with my react-navigation, componentWillUnmount() runs but once the saveSomething finishes, my alert box still pops up if I am not on the page.

Does anyone know why this would happen?

bryan
  • 8,879
  • 18
  • 83
  • 166
  • Is `saveSomething` called in your render ? – Treycos Jan 11 '19 at 15:48
  • @Treycos it is called with a touch action – bryan Jan 11 '19 at 15:50
  • If the touch action is fully working, your component has to already be mounted – Treycos Jan 11 '19 at 15:52
  • @Treycos I'm not sure what you're trying to tell me. I just need to figure out a way for the Success alert not to show up/do anything past the `isMounted` if statement if I leave the page before the saveSomething has gotten a response. – bryan Jan 11 '19 at 16:02
  • Are you worried that the react lifecycle functions won't work? It's a little anti pattern to do your own `isMounted` tracking. The react convention to do stuff like saving information is to use the `componentDidUnmount` lifecycle function. – Drew Reese Jan 11 '19 at 16:07
  • @DrewReese Yea, these Alert's are meant to be run when I am on that screen. If a user is not on that screen anymore and popups start showing up the user is going to be very confused. – bryan Jan 11 '19 at 16:11
  • Shoot, I meant `componentWillUmount`. I am on mobile. Can you provide codesandbox example that reproduces this? Can you also include the output of the console log in the success callback to your question? – Drew Reese Jan 11 '19 at 16:26
  • It'll take a lot of time. Not something I'm prepared to do atm. it's a React Native application so I'd have to gut everything, create a timeout for the function to take a while, etc. I honestly thought there was a common practice people used to make sure things don't happen when you leave a page. I've [heard](https://stackoverflow.com/questions/37521684/how-to-check-if-a-component-is-mounted-in-react-native-es6) my [method](https://stackoverflow.com/questions/39767482/is-there-a-way-to-check-if-the-react-component-is-unmounted) should work but it seems to be finicky – bryan Jan 11 '19 at 16:35
  • @bryan I'd maybe move the success callback into the component, let the `saveSomething` function set a state success value flag to true, then use `componentDidUpdate` to see that state had changed and to fire off the alert callback and set the success value flag back to false. Once components are unmounted, they should not be calling functions as by then they are destroyed. The exception is in asynchronous callbacks that get put into a queue and are called later, possibly after the component that created them are undefined. – Drew Reese Jan 11 '19 at 16:43

2 Answers2

1

Components that are further down the stack can receive calls to methods like componentWillReceiveProps and render even when they're not showing.

I think the best way is to handle your isMounted, inside componentDidMount and add a navigation listener, like didBlur which triggered once the screen unfocused :

const didBlurSubscription = this.props.navigation.addListener(
  'didBlur',
   payload => {
      this._isMounted = false;
   }
);

And make sure you removed the listener inside componentWillUnmount.

Read more here about navigation lifecycles : https://reactnavigation.org/docs/en/navigation-prop.html#addlistener-subscribe-to-updates-to-navigation-lifecycle

Emad Dehnavi
  • 3,262
  • 4
  • 19
  • 44
1

You can use isFocused method of navigation prop to check if the screen is focused or not.

https://reactnavigation.org/docs/en/navigation-prop.html

rht
  • 106
  • 9