1

I got the following react-navigation structure :

<NavigationContainer>
      {authToken ? (
        <Tab.Navigator>
          <Tab.Screen
            name='HomeScreen'
            component={HomeScreen}
          />
          <Tab.Screen
            name='SettingsScreen'
            component={SettingsScreen}
          />
        </Tab.Navigator>
      ) : (
        <Stack.Navigator>
          <Stack.Screen name="SignUpScreen" component={SignUpScreen} />
        </Stack.Navigator>
      )}
    </NavigationContainer>

How to navigate from SignUpScreen to HomeScreen and conversely :

// HomeScreen.js button :

onPress={() => {
  // remove authToken and then :
  navigation.navigate(`SignUpScreen`);
}}

Got the error message : The action 'NAVIGATE' with payload {"name":"SignUpScreen"} was not handled by any navigator. Do you have a screen named 'SignUpScreen'?

Same from SignUpScreen after authToken = true.

Is there a way to navigate from one stack to another in a ternary operator ? (Or trigger the index of the navigation to re-render the condition ?).

GuillaumeRZ
  • 2,656
  • 4
  • 19
  • 35
  • Encapsulate your `Navigation` tree with React Context and pass `authTokan` as a param to it – Hend El-Sahli Feb 06 '21 at 17:18
  • have you tried ```navigation.navigate('name of stack navigator', { screen: 'name of screen' });``` ? Upd, found similar stack [here](https://stackoverflow.com/questions/49826920/how-to-navigate-between-different-nested-stacks-in-react-navigation#60556168) – Mod3rnx Feb 06 '21 at 20:11
  • Yeah, it didn’t work either. – GuillaumeRZ Feb 06 '21 at 20:46

1 Answers1

0

Assuming what what you want to implement is an App that has a different navigation if you are logged in or out, I would suggest using the Switch navigator. In your case, your error it is most likely caused because the signup screen does not exist in the tree of both stack navigators. I'll post the entire main code but the part you should take a look is this:

const Navigator = createSwitchNavigator({
        Main: MainTabNavigator,
        Auth: AuthNavigator,
        SplashScreen: SplashScreen,
        Onboarding: Onboarding,
      }, {
        initialRouteName: 'SplashScreen',
        headerMode: 'none'
    });

The rest:

import React from "react";
import { createStackNavigator, createBottomTabNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
import {ThemeProvider} from 'styled-components'
import {configureStore} from "./redux/store"
import { Provider } from 'react-redux'

const theme = {
  primaryColor: '#3F51B5',
  darkPrimaryColor: '#303F9F',
  containerBackgroundColor: '#FFFFFF',
  lightPrimaryColor: '#C5CAE9',
  accentColor: '#FF5722',
  backgroundColor: 'white',
  font: 'Lato-Regular',
  fontBold: 'Lato-Bold'
}

const ConfigNavigator = createStackNavigator({
  Config: ConfigScreen,
  SettingsScreen: SettingsScreen,
  ...coreRoutes
}, {
  initialRouteName: 'Config',
  headerMode: 'none'
});

const HomeNavigator = createStackNavigator({
  ...coreRoutes
}, {
  initialRouteName: 'HomeScreen',
  headerMode: 'none'
});

const PlacesNavigator = createStackNavigator({
  Places: PlacesScreen,
  POI: POIScreen,
}, {
  initialRouteName: 'Places',
  headerMode: 'none'
});

const PinnedNavigator = createStackNavigator({
  Pinned: PinnedScreen,
  POI: POIScreen,
}, {
  initialRouteName: 'Pinned',
  headerMode: 'none'
});

const MainTabNavigator = createBottomTabNavigator({
  Home: HomeNavigator,
  Places: PlacesNavigator,
  Pinned: PinnedNavigator,
  Chat: ChatScreen,
  Config: ConfigNavigator,
}, {
  initialRouteName: 'Home',
  tabBarPosition: "bottom",
  swipeEnabled: false,
  tabBarComponent: props => {
    return <TabNavigation {...props}
    items={[
      {
        text: Strings['home'], icon: { name: "home", type: "MaterialCommunityIcons" },
        route: "Home"
      },
      {
        text: Strings['places'], icon: { name: "map-marker-multiple", type: "MaterialCommunityIcons"},
        route: "Places"
      },
      {
        text: Strings['pinned'], icon: { name: "pin", type: "MaterialCommunityIcons" },
        route: "Pinned"
      },
      {
        text: Strings['chat'], icon: { name: "wechat", type: "MaterialCommunityIcons" },
        route: "Chat"
      },
      {
        text: Strings['settings'], icon: { name: "settings", type: "MaterialCommunityIcons" },
        route: "Config"
      }
    ]}
    />
  }
});

const AuthNavigator = createStackNavigator({
  Registration: RegistrationScreen,
}, {
  initialRouteName: 'Registration',
  headerMode: 'none'
});

const Navigator = createSwitchNavigator({
    Main: MainTabNavigator,
    Auth: AuthNavigator,
    SplashScreen: SplashScreen,
    Onboarding: Onboarding,
  }, {
    initialRouteName: 'SplashScreen',
    headerMode: 'none'
});

const AppContainer = createAppContainer(Navigator)

let store = configureStore();

class App extends React.Component {

  constructor(){
      super();
      this.theme = new Theme(theme);
  }

  render(){
    return <Provider store={store}>
              <ThemeProvider theme={this.theme.getTheme()}>
                  <AppContainer/>
              </ThemeProvider>
          </Provider>
  }
};

export default App;

From then, you just navigate to Auth or Main and the entire navigator tree changes.

sebastianf182
  • 9,844
  • 3
  • 34
  • 66
  • Seems to be outdated for react-navigation 5 ( https://reactnavigation.org/docs/upgrading-from-4.x/#switch-navigator ). My ternary came from this link, and I'm a not sure you can navigate from on stack to another. – GuillaumeRZ Feb 06 '21 at 19:26
  • If I understand the v5 docs correctly, then you don't actually need to navigate to the SignUpScreen, but just reset the token should be enough for the navigator to show up. How are you reading the authToken? If you are reading that from redux or using s subscriber then that should solve your problem. – sebastianf182 Feb 06 '21 at 23:47
  • The authToken is actually read from AsyncStorage (getItem) – GuillaumeRZ Feb 07 '21 at 07:51