nigranac
nigranac

Reputation: 203

How to change initial screen in Route.Js with Async Storage in React Native

I am trying to change the entrance point my application in Router.js to not show the user Onboarding screens second time. Basically I set an async storage value. When the onboarding is finished the value return true. As the async storage functions are async, the return statement in Router.js is not waiting the it to return a value. So I can’t change the initial point of my navigation system.

index.js

AppRegistry.registerComponent(appName, () => Router);

Router.js

function Router() {

let first ="App"
let second ="GetStarted"



  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={checkFirstUsage().then(data=>data?second:first)} screenOptions={{headerShown: false} }>
        <Stack.Screen name="GetStarted" component={GetStarted} />
        <Stack.Screen name="EnterPoem" component={EnterPoem} />
        <Stack.Screen name="Interest" component={Interested} />
        <Stack.Screen name="Begin" component={Begin} />
        <Stack.Screen name="App" component={App} />
      </Stack.Navigator>
    </NavigationContainer>
    
  );
}

checkFirstUsage

const checkFirstUsage = async () => {
    try {
      const value = await AsyncStorage.getItem('@isAsyncStorageSet')
      if(value === null) {
      
      return true
      }
      else{
        return false;
      }
    } catch(e) {
      console.log(e)
    }
  }

any help is appreciated

Upvotes: 1

Views: 1075

Answers (1)

Adriano Machado
Adriano Machado

Reputation: 170

I think the best approach when you want to manage separated stack navigators is something like

index.js

import React, {useState, useEffect} from 'react';
import OnBoardingRoutes from './onBoarding.routes';
import AppRoutes from './app.routes';
import checkFirstUsage from "./checkFirstUsage/path";


const Routes: React.FC = () => {
  const [loading, setLoading] = useState(true)
  const [firstUsage,setFirstUsage] =useState(null);

  useEffect(() => {
     async function check() {
          const fU = await checkFirstUsage()
          setFirstUsage(fU)
          setLoading(false)
     }

     check()
  },[])

  if (loading) return null  // or any better component

  return firstUsage ? <OnBoardingRoutes /> : <AppRoutes />;
};

export default Routes;

And then you have your two stacks navigator, with their respective routes

onBoarding.routes

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import OnBoardingPage1 from '../pages/OnBoardingPage1';
import OnBoardingPage2 from '../pages/OnBoardingPage2';


const App = createStackNavigator();

const OnBoardingRoutes: React.FC = () => (
  <App.Navigator
    initialRouteName="GetStarted"
    screenOptions={{
      headerShown: false,
    }}
  >
    <App.Screen name="OnBoardingPage1" component={OnBoardingPage1} />
    <App.Screen name="OnBoardingPage2" component={OnBoardingPage2} />

  </App.Navigator>
);

export default OnBoardingRoutes;

and your App routes

app.routes

    import React from 'react';
    import { createStackNavigator } from '@react-navigation/stack';
    import AppPage1 from '../pages/AppPage1';
    import AppPage2 from '../pages/AppPage2';

    
    const App = createStackNavigator();
    
    const AppRoutes: React.FC = () => (
      <App.Navigator
        initialRouteName="App"
        screenOptions={{
          headerShown: false,
        }}
      >
        <App.Screen name="AppPage1" component={AppPage1} />
        <App.Screen name="AppPage2" component={AppPage2} />

      </App.Navigator>
    );
    
    export default AppRoutes;

and your Router component will looks like

import React from "react"
import Routes from "./index";


    function Router() {
    
      return (
        <NavigationContainer>
           <Routes/>
        </NavigationContainer>
        
      );
    }
export default Router;

Upvotes: 3

Related Questions