8
votes

I've set up a StackNavigator which will fire a redux action to fetch data on componentDidMount, after navigating to another screen and going back to the previous screen, componentDidMount is no longer firing and I'm presented with a white screen. I've tried to reset the StackNavigator using StackActions.reset but that just leads to my other screens not mounting as well and in turn presenting an empty screen. Is there a way to force componentDidMount after this.props.navigation.goBack()?

Go Back Function

_goBack = () => {
  this.props.navigation.goBack();
};

Navigation function to new screen

_showQuest = (questId, questTitle ) => {
  this.props.navigation.navigate("Quest", {
    questId,
    questTitle,
  });
};

Edit : Hi , I'm still stuck on this matter and was wondering if the SO Community has a solution to force componentDidMount to be called after Navigation.goBack() is called or rather how to Unmount the component after this.props.navigation.navigate is called

2
How are you rendering your components? It might be that your other component is not actually unmounted when the navigation changes, and therefor componentDidMount will not be called again when you go back.Tholle
After navigating to a new screen, componentDidMount will be called the first time and after going back to the previous screen, it is no longer called. How do you forcefully unmount the screen after navigating to a new screen?Ash Rhazaly

2 Answers

1
votes

The didFocus event listener didn't work for me.

I found a different listener called focus which finally worked!

componentDidMount() {
    const { navigation } = this.props;
    
    this.focusListener = navigation.addListener('focus', () => {
        // call your refresh method here
    });
}

componentWillUnmount() {
    // Remove the event listener
    if (this.focusListener != null && this.focusListener.remove) {
        this.focusListener.remove();
    }
}
9
votes

The components are not removed when the navigation changes, so componentDidMount will only be called the first time it is rendered.

You could use this alternative approach instead:

class MyComponent extends React.Component {
  state = {
    isFocused: false
  };

  componentDidMount() {
    this.subs = [
      this.props.navigation.addListener("didFocus", () => this.setState({ isFocused: true })),
      this.props.navigation.addListener("willBlur", () => this.setState({ isFocused: false }))
    ];
  }

  componentWillUnmount() {
    this.subs.forEach(sub => sub.remove());
  }

  render() {
    if (!this.state.isFocused) {
      return null;
    }

    // ...
  }
}