abdi
abdi

Reputation: 589

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>
    );
};

Upvotes: 15

Views: 25322

Answers (4)

Michele
Michele

Reputation: 75

From inside your Tab component you can get params of the parent navigation.

const NetworkUsersScreen = ({navigation}) => {
   const parent_navigation = navigation.getParent().getState();
   const network = parent_navigation.routes[parent_navigation.index].params.network;
}

Upvotes: 0

Abdullah Patel
Abdullah Patel

Reputation: 1

const Stack = createStackNavigator();
function AppNavigator(props) {
    const { cartCount } = props;
    return (
        <NavigationContainer>
              <Stack.Screen {...props} name="MainScreen" component={() => <MyTabs cartCounts={cartCount}></MyTabs>} options={{ headerShown: false }} countProp={cartCount} initialParams={{ 'count': cartCount }} />
             </Stack.Navigator>
        </NavigationContainer>
    )
}

function mapStateToProps(state) {
    return {
        cartCount: state.cart.cartCount,
    }
}

export default connect(mapStateToProps, {})(AppNavigator);

And your tab component like

function MyTabs(props) {
let cartCount = props.cartCounts;
return (
    <BottomTab.Navigator
        screenOptions={{
            tabBarStyle: { position: 'absolute' },
            tabBarStyle: styles.tabbarStyle
        }}>
        <BottomTab.Screen name="CartScreen" component={CartScreen} options={{ headerShown: false }}
            options={{
                headerShown: false,
                tabBarIcon: ({ focused, tintColor }) => (
                    <View style={styles.cartIconView}>
                        <Image
                            square
                            source={bottomCart}
                           
                        />
                        <Badge style={[GlobalStyles.badge, styles.count, {
                        }]}>
                            <Text style={[GlobalStyles.badgeText, styles.countText]}>{cartCount}</Text>
                        </Badge>
                    </View>
                ),
            }} />
    
    </BottomTab.Navigator >
);

Upvotes: 0

Garvit Tyagi
Garvit Tyagi

Reputation: 139

You can set initial params to your screens.

const PostsTabNav = createMaterialTopTabNavigator();
const PostsMainNav = (props) => {
    const temp = props.route.params.network
    return (
        <PostsTabNav.Navigator>
            <PostsTabNav.Screen name="NetworkPosts" component={NetworkPostsScreen} initialParams={network:temp}/>
            <PostsTabNav.Screen name="NetworkUsers" component={NetworkUsersScreen} initialParams={network:temp}/>
        </PostsTabNav.Navigator>
    );
};

Upvotes: 13

satya164
satya164

Reputation: 10145

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

Upvotes: 17

Related Questions