Search code examples
react-nativereact-navigationreact-navigation-bottom-tab

addListeners doesn't work from time to time - React native tab navigation


I've used tab navigation of react-navigation. I need to call a loadData function in componentDidMount every time the tab is pressed. So I'm using addListener in it. But the problem is that it tooks too long to display the data. Sometimes it works seamlessly and sometimes it only shows "Loading Data..." all the time. Am I using the addListener correctly? Thanks in advance.

Home.js

state = {
  storageCheck: true
};

componentDidMount() {
    this._unsubscribe = this.props.navigation.addListener('willFocus', () => {
      this.loadData();
    });
}

componentWillUnmount() {
    this._unsubscribe.remove();
}

loadData = () => {
    this.setState({
        storageCheck: false
    })
}

render() {
if (this.state.storageCheck) {
  return <View>
    <Text>Loading Data...</Text>
  </View>
}
return (
    <View>
        <Text>Data</Text>
    </View>
)}

Tab navigation

const TabNavigator = createBottomTabNavigator({
  Home: {
    screen: Home
  },
  Profile: {
    screen: Profile,
    navigationOptions: ({ navigation }) => ({
      // title: 'Profile',
    })
  },
  Setting: {
    screen: Setting,
  }
},
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, tintColor }) => {
        const { routeName } = navigation.state;
        let iconName;
        if (routeName === 'Home') {
          iconName = 'home';
        } else if (routeName === 'Profile') {
          iconName = 'account-circle';
        } else if (routeName === 'Setting') {
          iconName = 'settings';
        }

        return <MaterialIcons name={iconName} size={28} color={tintColor} />;
      },
    })
  }
);

export default createAppContainer(TabNavigator);

Solution

  • In react-navigation v4.

    You can use await-async functions.

    state = {
      storageCheck: true,
      loader: true,
      someData: null
    };
    
    componentDidMount() {
        this._unsubscribe = this.props.navigation.addListener('willFocus', () => {
          this.loadData();
        });
    }
    
    componentWillUnmount() {
        this._unsubscribe.remove();
    }
    
    loadData = async() => {
        this.setState({
            someData: await AsyncStorage.getItem("SOME_KEY"),
            storageCheck: false,
            loader: false
        })
    }
    
    render() {
      return (
          <View>
           {this.state.someData ? (
            <Text>data is loaded</Text>
           ) : (
            <Text> loading ... </Text>
           )}
          </View>
      )
    }

    cheers!