reactjsreact-nativereact-navigationreact-navigation-v5react-navigation-bottom-tab

Passing params to tab navigator React Navigation 5


I’m using materialTopTabs and it seems like this loads all the screens in the navigator once its mounted. I have a screen List and inside it a tab navigator with 2 screens: Posts and Users. These two screen both depend on params passed from List. However, i am only able to pass params to one of the screens using this method:

navigation.navigate('PostsTabNav', {
  params: {
    network: item,
  },
  screen: 'NetworkPosts' //or NetworkUsers
});

I have tried to pass the params to my navigator directly by doing this:

navigation.navigate('PostsTabNav', {
  network: item
});

The first option only allows me to pass to one screen. The second option allows me to access the params inside the navigator like this:

const PostsTabNav = createMaterialTopTabNavigator();
const PostsMainNav = (props) => {
    const temp = props.route.params.network; //params here

    return (
        <PostsTabNav.Navigator>
            <PostsTabNav.Screen name="NetworkPosts" component={NetworkPostsScreen} />
            <PostsTabNav.Screen name="NetworkUsers" component={NetworkUsersScreen} />
        </PostsTabNav.Navigator>
    );
};

Is there a way to pass temp to both my screens? If not is there a better way to handle this situation?

Here's the code for the StackNavigator

const NetworkListStackNav = createStackNavigator();
export const NetworksListNavigator = () => {
    return (
        <NetworkListStackNav.Navigator>
            <NetworkListStackNav.Screen name="List" component={ListScreen} />
            <NetworkListStackNav.Screen name="PostsTabNav" component={PostsMainNav} />
        </NetworkListStackNav.Navigator>
    );
};

Solution

  • Pass params to the navigator and then expose it to the tabs using React Context.

    Create a context in a separate file which you can import in both your navigator and screens:

    export const NetworkContext = React.createContext();
    

    Then provide the params in the context:

    const PostsTabNav = createMaterialTopTabNavigator();
    
    const PostsMainNav = ({ route }) => {
      return (
        <NetworkContext.Provider value={route.params.network}>
          <PostsTabNav.Navigator>
            <PostsTabNav.Screen name="NetworkPosts" component={NetworkPostsScreen} />
            <PostsTabNav.Screen name="NetworkUsers" component={NetworkUsersScreen} />
          </PostsTabNav.Navigator>
        </NetworkContext.Provider>
      );
    };
    

    In your screen component, use the context:

    const network = React.useContext(NetworkContext);
    

    Also see https://reactnavigation.org/docs/hello-react-navigation#passing-additional-props