Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

change states as well as navigating to another screen

I have a navigation container that calls a function to my stack. I would like to navigate to a tab screen from a stack screen AND change a state in that tab screen. I have given some code below and a demo. In the demo you can see on screen3(stack screen) I am trying to navigate to Home(tab screen) and change a state so that it renders the MapHome screen.

I am unsure how to pass the state to the bottom tab screen without rendering it elsewhere. I appreciate any insight more than you know.

here is my demo as well as some code below of App.js. You must run the demo in IOS or android, it will not work for web.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

import { NavigationContainer } from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '@expo/vector-icons';

import Home from './Home'
import ListHome from './screens/screen1'
import MapHome from './screens/screen2'
import Screen3 from './screens/screen3'

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (

    <Stack.Navigator
     initialRouteName="Home">        
      <Stack.Screen name="Home" component= {Home} options={{headerShown: false}}/>
      <Stack.Screen name="Screen1" component= {ListHome} options={{headerShown: false}}/> 
       <Stack.Screen name="Screen2" component= {MapHome} options={{headerShown: false}}/>
    </Stack.Navigator>
);
}


export default function App() {

  return (
   <NavigationContainer>
    <Tab.Navigator
    initialRouteName="Home"
    screenOptions={{
      tabBarActiveTintColor: '#F60081',
      tabBarInactiveTintColor: '#4d4d4d',
      tabBarStyle: {
        backgroundColor: '#d1cfcf',
        borderTopColor: 'transparent',
      },
    }} 
  >
    <Tab.Screen
      name="Home"
      component={MyTabs}
      options={{
        tabBarLabel: 'Home',
        headerShown: false,
        tabBarIcon: ({ color, size }) => (
          <MaterialCommunityIcons name="home" color={color} size={size} />
        ),
      }}
    />

     <Tab.Screen
      name="Screen3"
      component={Screen3}
      options={{
        tabBarLabel: 'Screen3',
        headerShown: false,
        tabBarIcon: ({ color, size }) => (
          <MaterialCommunityIcons name="account-group" color={color} size={size} />
        ),
      }}
    />
    
  </Tab.Navigator>
</NavigationContainer>
);
}

const Stack = createStackNavigator();
like image 422
Justin Priede Avatar asked Dec 18 '21 02:12

Justin Priede


People also ask

What is nested navigation?

Nesting navigators means rendering a navigator inside a screen of another navigator, for example: function Home() { return ( <Tab.

What is navigate replace?

navigation. replace - replace the current route with a new one. push - push a new route onto the stack. pop - go back in the stack.


1 Answers

You can pass a parameter from Screen3 to the Home screen.

I have forked your demo and did some small refactoring (including changing from Class to Function components just for preference) so you may need to adapt it to your needs. You can find it here.

In Screen3 you can modify your onPress logic to the following:

navigation.navigate('Home', {
  screen: 'Home',
    params: {
      componentToShow: 'Screen2'
    }
});

Here's a breakdown of why you are seeing Home twice:

navigation.navigate('Home', {       // <-- Tab.Screen name. 
  screen: 'Home',                   // <-- Stack.Screen name.
    params: {
      componentToShow: 'Screen2'
    }
});

With this code you are now passing a route.param to the Home screen. I've included a useEffect to run any time route.params changes.

const [whichComponentToShow, setComponentToShow] = React.useState("Screen1");

React.useEffect(() => {
  if(route.params && route.params.componentToShow) {
    setComponentToShow(route.params.componentToShow);
  }
}, [route.params]);

Now, whenever a User navigates to the Home screen and a componentToShow route parameter is provided, the Home screen will update.

like image 109
Dan Avatar answered Nov 15 '22 09:11

Dan