7

I am using React Navigation in my app. How can I refresh the data on my previous panel when going back to it?

A practical example would be: I am currently in Panel A, I navigate to Panel B where I update data in my database which is displayed in Panel A. After I goBack() to Panel A after changing the data in the database I wish Panel A has now rerendered and holds the new data from the database.

I have read that I can pass a custom refresh function as params to the child class and call it before navigating back, however I think this is not a neat way to achieve what I want since I update a component which is not yet mounted and I can just throw an error.

GIV
  • 405
  • 3
  • 9
  • 16

6 Answers6

6

This is how i achieved!

In Panel A

refreshFunction()
{
    //your refresh code should be here
}

 <TouchableOpacity onPress={()=>{
   this.props.navigation.navigate('PanelB', {refreshFunction: this.refreshFunction});
 }}>
    Redirect to Panel B
 </TouchableOpacity>

In Panel B

const refreshFunction = this.props.navigation.state.params.refreshFunction;
if(typeof refreshFunction === 'function')
{
  refreshFunction();                
  //your back function
  this.goBack();
}
Jitender Badoni
  • 218
  • 1
  • 9
  • Related solutions in issue: https://github.com/react-navigation/react-navigation/issues/922 – steviesh Sep 12 '18 at 06:34
  • React navigation added one more approach (i guess createStackNavigator) which unmount the compoenent in redirect action. So each time render component will trigger componentDidMount method. – Jitender Badoni Sep 12 '18 at 08:17
2

React Navigation provides listeners which can be used for this exact scenario.

For example, attach a listener to Panel A, which will re-fetch the updated data when focused (i.e. when Panel A is "popped back" to):

componentDidMount() {
  const { fetchDatabaseData, navigation } = this.props
  fetchDatabaseData()
  this.willFocusListener = navigation.addListener(
    'willFocus',
    () => {
      fetchDatabaseData()
    }
  )
}

componentWillUnmount() {
  this.willFocusListener.remove()
}
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Bataleon
  • 3,194
  • 3
  • 21
  • 26
1

After so much searching, conclusion: yes you can:

render(){
...
   <NavigationEvents
      onWillFocus={() => {
      //Call whatever logic or dispatch redux actions and update the screen!
      }}
   />
...
}

Source: https://github.com/react-navigation/react-navigation/issues/1171

David Schumann
  • 13,380
  • 9
  • 75
  • 96
Duverney
  • 11
  • 3
0

Using redux + firebase I had the problem where the observable data from firebase.on('value', snapshot => { dispatch(data) } that was mappedToProps would update the redux store on save, before the component that listed that data returned to view onBack(), so no re-render would trigger in the list. I solved it by comparing past to current props and re-triggering the firebase.on fn only when the props did not match. This is better than always firing when the list component is navigated to, but I'd prefer a solution that forcefully triggers a re-render without calling the firebase fn at all.

  componentDidUpdate(prevProps) {
    if (prevProps.data !== this.props.data) this.props.fetchdata();
  }
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Andrew
  • 1,406
  • 1
  • 15
  • 23
0

As per navigation docs for navigation events

function Profile({ navigation }) {
  React.useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      // do something
    });

    return unsubscribe;
  }, [navigation]);

  return <ProfileContent />;
}
Mohamed Daher
  • 609
  • 1
  • 10
  • 23
-3

If you have may scenarios, like this, you can use redux, which help you to manage data across tabs/screen and in the component because reduces is connected to store, in the redux store entire application state is managed.

RANVIR GORAI
  • 1,226
  • 11
  • 10