2

how to give dynamic initial route name in the react-navigation? if the unit exists we have to redirect to another route or else we have to take user another route.

Note: I'm creating a bottom tab navigator in which I have to set an initial route to that particular bottom tab navigator.

(Not the authentication flow)

import React, {Component} from 'react';
import {createAppContainer} from 'react-navigation';
import {createMaterialBottomTabNavigator} from 'react-navigation-material-bottom-tabs';
... imports
function getInitialScreen() {
  AsyncStorage.getItem('unit')
    .then(unit => {
      return unit ? 'Home' : 'secondTab';
    })
    .catch(err => {

    });
}

const TabNavigator = createMaterialBottomTabNavigator(
  {
    Home: {
       screen: HomeScreen,
       navigationOptions: {
        .....navigation options
       },
     },
    secondTab: {
      screen: secondTab,
    },
  },
  {
    initialRouteName: getInitialScreen(),
  },
); 
export default createAppContainer(TabNavigator);
Abhiram
  • 1,540
  • 1
  • 11
  • 25

5 Answers5

1

See according to the docs, initialRoute name should not be a async func .

So ideally what you should do is , anyways you need a splashscreen for your app right, where you display the logo and name of app. Make that page the initialRoute and in its componentDidMount, check for the async function and navigate to ddesired page.

Like what ive done :

createSwitchNavigator(
    {
      App: TabNavigator,
      Auth: AuthStack,
      SplashScreen: SplashScreen,
    },
    {
      initialRouteName: 'SplashScreen',
    },
  ),

And inside SplashScreen im doing :

componentDidMount(){
 if (token) {
      this.props.navigation.navigate('App');
    } else {
      this.props.navigation.navigate('Auth');
    }

}

Hope its clear. Feel free for doubts

Gaurav Roy
  • 11,175
  • 3
  • 24
  • 45
  • I'm creating a bottom tab navigator in which I have to set an initial route, not for the SwitchNavigator. – Abhiram Feb 18 '20 at 10:33
1

As you can see here:

If you need to set the initialRouteName as a prop it is because there is some data that you need to fetch asynchronously before you render the app navigation. another way to handle this is to use a switchnavigator and have a screen that you show when you are fetching the async data, then navigate to the appropriate initial route with params when necessary. see docs for a full example of this.

Take a look at here.

You'll find more description!

Also quick fix for this situation is check your condition inside SplashScreen componentDidMount() function

Example of SplashScreen :

componentDidMount(){
  AsyncStorage.getItem('unit')
    .then(unit => {
      if(unit){
       this.props.navigation.navigate('Home')
      }else{
       this.props.navigation.navigate('secondTab')
      }
    })
    .catch(err => {

    });
}
Akila Devinda
  • 5,054
  • 3
  • 19
  • 35
-1

You can check the condition on the main page or App.js

render() {
  const status = get AsyncStorage.getItem('unit');
  if(status != null)
  { return <Home/> }
  else
  { return <AnotherScreen/> }
}

But we can switch between pages if we use stacknavigator or switchnavigator.. We cant goto the particular tabs directly according to my knowledge. (Correct me if I am wrong).

Abhiram
  • 1,540
  • 1
  • 11
  • 25
Vanns35
  • 466
  • 4
  • 15
  • sorry, I didn't get you. After app rendering(am not at the root level) creating the bottom tab navigation. – Abhiram Feb 18 '20 at 10:38
-1

The official documentation gives you this example to achieve pretty much what you want:

isSignedIn ? (
  <>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Profile" component={ProfileScreen} />
    <Stack.Screen name="Settings" component={SettingsScreen} />
  </>
) : (
  <>
    <Stack.Screen name="SignIn" component={SignInScreen} />
    <Stack.Screen name="SignUp" component={SignUpScreen} />
  </>
)
Roy Martinez
  • 335
  • 5
  • 6
  • i got error ***A navigator can only contain 'Screen', 'Group' or 'React.Fragment' as its direct children (found ' ? ('). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.*** – famfamfam Apr 07 '22 at 08:22
  • You need then to pass it as argument and then using it – Roy Martinez Apr 08 '22 at 17:50
-2

Ok So in your navigation page create state and change its value accordingly AsyncStorage like

render() {
  const status = get AsyncStorage.getItem('unit');
  if(status != null)
  { setState({ name : 'Home'}) }
  else
  { setState({ name : 'anotherTab'}) }
} 

then pass that state to tabNavigation

initialRouteName: this.state.name,

and this state , setState functions are classed based so you have to use useState instead to initial state on your page

Vanns35
  • 466
  • 4
  • 15