componentDidMount is not working when redirect to

2019-08-22 02:38发布

问题:

I am having componentDidMount to list set of files(images) in a screen A, from this screen A I am having another screen B link where I can see detailed view of a file and there I have an option to delete a document.

When screen A is called using

  <TouchableOpacity style={Styles.HomeButton} onPress={ () => this.props.navigation.navigate('Gallery')}>
     <Text style={Styles.HomeButtonText}>View Photos</Text>
  </TouchableOpacity>

componentDidMount working fine, But when I delete a file (i am using react-native-fs) on unlink callback I am calling the navigation like

this.props.navigation.navigate('Gallery');

Which is working fine redirecting to Screen A, but componentDidMount is not working which means I can still see that deleted file in the list. i.e Screen A is not refreshing, is there any possible solution?

回答1:

In react-navigation, the component will not unmount if you navigate to other screens unless you reset the stack in stack navigation. So when you come back to the previous screen, as it is already mounted, componentDidMount will not trigger.

You can bind a react navigation event listener to trigger some piece of code when you get back to the screen.

this.focusListner = this.props.navigation.addListener("didFocus",() => {
  // Update your data
});

Don't forget to remove event listeners while you unmount the component.

componentWillUnmount() {
    // remove event listener
    this.focusListner.remove();
}



回答2:

Possible reason, why your componentDidMount() is not working, is because screen B may be possible a modal.

In the case of modals, the previous component does not unmount, and the next screen just opens upon it. So when you go back to the previous screen, it does not mount again. That's why your list is not updating.

Solution

You have to change the state of the component which is supposed to rerender. The best solution here, and which I also use, is a state management library like Redux. So when you delete the item from screen B, just also update the redux store accordingly. So every component that using that reducer will rerender and you can also save one hit to your server.



回答3:

You should consider refreshing your list on navigation's didFocus event. Clearly if you are using a stack navigation with A -> B, and once you delete your file from B and goes back to A, provided that A is already in the stack so the didMount wont work when you navigate back.

So, ideally you must refresh your list on the didFocus event of the navigation using some kind of flag set in redux when you delete the file and once you get back to A you read the status of the flag and refresh your list accordingly.

You can refer this to better understand the navigation props and the lifecycle events



回答4:

You may want to check the NavigationEvents API here : https://reactnavigation.org/docs/en/navigation-events.html .

To solve your problem you want to use the navigation event onDidFocus instead of componentDidMount !

This is a way easier way to than to use the imperative API as it takes care of subscribing and unsubscribing the listeners.