Search code examples
react-nativereact-hooksreact-navigationside-effectsreact-lifecycle

Can not implement callback inside of useFocusEffect from React-navigation


I have React-native app with topTabNavigator with three tabs. And usually componentDidMount and componentWillUnmount lifecycle methods don't work when the user changes the tab. Therefore instead of them I decided to use for the side effects onWillFocus and onDidFocus from React-Navigation. And before 5th version of this great library https://reactnavigation.org/ it was possible to import NavigationEvents component and put it to the view with focused callbacks:

import { NavigationEvents } from 'react-navigation';

class MyTeamScreen {
  const store = this.props.store;
  const members = store.members;

  return (
  <View>
    <NavigationEvents
      onWillFocus={payload => store.getTeamMebers()}
      onDidFocus={payload => store.dispose()}
    />
    <MymebersList team={members} />
  </View>
 );
}
export default MyScreen;

But at the moment there is no like this way after the upgrade of react reactnavigation library, because NavigationEvents is deprecated. And only one way to use useFocusEffect. And this is my hook:

function FetchMembers(store) {
  useFocusEffect(
  React.useCallback(() => {
      return () => store.getMembers();
    }, [store])
  );

  return null;
}

Class component:

class MyTeamScreen {
  const store = this.props.store;
  const members = store.members;

  return (
  <View>
    <FetchMembers store={store} />
    <MymebersList team={members} />
  </View>
 );
}

But I'm getting the error:

enter image description here

And I checked the store was initialized inside of the hook, but it can not call a method from it, because it's undefined. Can you tell me please what I'm doing wrong? Is it a good way to use react-navigation methods instead of lifecycles componentDidMount and componentWillUnmount? Or maybe you could recommend me please the better way how to implement side effect when the user is changing the tab?


Solution

  • Looking at your code, I'm curious (but not so sure) that you may refer to the incorrect props?

    Would you mind trying this? Because the first parameter of functional component is props. To refer to props.store, you can use object destructuring like this

    function FetchMembers({store}) {
      useFocusEffect(
      React.useCallback(() => {
          return () => store.getMembers();
        }, [store])
      );
    
      return null;
    }
    

    or

    function FetchMembers(props) {
      useFocusEffect(
      React.useCallback(() => {
          return () => props.store.getMembers();
        }, [props.store])
      );
    
      return null;
    }