Search code examples
javascriptreact-nativereact-navigationasyncstoragetabnavigator

Reload AsyncStorage data every time tabbar screen is displayed using React Navigation


I am using React Navigation in a React Native app I'm building and I have a set of screens that are in a TabNavigator. One of the screens may change something in AsyncStorage which will need to reflected in another screen.

I tried various different things including setting the tabBarOnPress property in the navigationOptions of the second screen, but that did not work. I also tried using componentDidUpdate() and componentWillUpdate(), but nothing.

What is the accepted way to do this?

UPDATE 1 I managed to have it such that I am capturing when the tab is pressed by doing

static navigationOptions = {
    headerTitle: 'Screen B',
    tabBarLabel: 'Screen B',
    tabBarOnPress: (obj) => {
      // load data here....

      // this causes this screen to actually appear
      obj.jumpToIndex(obj.scene.index)
     }
};

Now, I need to load the data in using

loadFavouritesData() {
    // load from AsyncStorage here and update state
}

However, using this.loadFavouritesData() in the arrow function in tabBarOnPress doesn't do it as it's not the correct this. What can I do after this?


Solution

  • I think I found the solution to this. It's a rather hacky one but it works.

    Carrying on from the update posted in the question, I further do this in componentWillMount():

    componentWillMount() {
        this.props.navigation.setParams({
           currentScreen: this,
        })
    }
    

    This makes the navigation object carry around a reference to the current screen. I can then modify the navigationOptions to be an arrow function which takes a navigation object:

    static navigationOptions = ({ navigation }) => ({
        headerTitle: 'Screen B',
        tabBarLabel: 'Screen B',
        tabBarOnPress: (obj) => {
    
           // load data here by getting currentScreen from the navigation params
    
           navigation.state.params.currentScreen.loadFavouritesData()
           obj.jumpToIndex(obj.scene.index)
        }
    })
    

    Not the cleanest solution, but it seems to work for now, at least until I start getting into Redux.