skip to Main Content

Trying to create an app that has an onboarding sequence that is only shown on the first launch. During onboarding, the user is asked to enter their name and I am able to use whether or not there is a name value stored to determine if the app is being launched for the first time or if there is an existing user on the device. The idea is to assign a variable to a string value that corresponds to the first element to render; <Onboarding /> or <Home />, bypassing onboarding on 2nd… 3rd… launch etc. However, when I assign the variable values outside of the return() statement, I get the error: Property 'initial' doesn't exist in Expo GO. I am a beginner to React Native and mobile app development so sorry if the fix is super obvious; any help would be appreciated! Below is an abridged version of the code in my runtime App.js file. (Note that the username has been stored Async with the key ‘user’. Thanks again!

import AsyncStorage from '@react-native-async-storage/async-storage';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native'
import { createNativeStackNavigator} from '@react-navigation/native-stack'
import React, { useEffect, useState } from 'react'

import Onboarding from './screens/Onboarding'
import Onboarding2 from './screens/Onboarding2'
import Onboarding3 from './screens/Onboarding3'
import Onboarding4 from './screens/Onboarding4'
import Onboarding5 from './screens/Onboarding5'
import Home from './appscreens/Home'
import About from './appscreens/About'
import Name from './screens/Name'


const Stack = createNativeStackNavigator()

const navTheme = {
  colors: {
    background: 'transparent'
  }
}

export default function App() {

  const [user, setUser] = useState({})

  const findUser = async () => {
    const result = await AsyncStorage.getItem('user')
    setUser(JSON.parse(result))
    console.log(user)
  }

  useEffect(() => {
    findUser()
  }, [])

  if (!user.name){const initial = "Onboarding"}
  if (user.name){const initial = "Home"}

  return (
    <NavigationContainer theme={navTheme}>
      <Stack.Navigator initialRouteName={initial} screenOptions={{headerShown: false}}>
        <Stack.Screen name="Onboarding" component={Onboarding} />
        <Stack.Screen name="Onboarding2" component={Onboarding2} />
        <Stack.Screen name="Onboarding3" component={Onboarding3} />
        <Stack.Screen name="Onboarding4" component={Onboarding4} />
        <Stack.Screen name="Onboarding5" component={Onboarding5} />
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="About" component={About} />
        <Stack.Screen name="Name" component={Name} />
      </Stack.Navigator>
    </NavigationContainer>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
}); ```

2

Answers


  1. The compiler error is apparent. You are accessing variable initial outside its defined scope:

    Refactor code as below :

    
    import AsyncStorage from "@react-native-async-storage/async-storage";
    import { NavigationContainer, DefaultTheme } from "@react-navigation/native";
    import { createNativeStackNavigator } from "@react-navigation/native-stack";
    import React, { useEffect, useState } from "react";
    
    import Onboarding from "./screens/Onboarding";
    import Onboarding2 from "./screens/Onboarding2";
    import Onboarding3 from "./screens/Onboarding3";
    import Onboarding4 from "./screens/Onboarding4";
    import Onboarding5 from "./screens/Onboarding5";
    import Home from "./appscreens/Home";
    import About from "./appscreens/About";
    import Name from "./screens/Name";
    
    const Stack = createNativeStackNavigator();
    
    const navTheme = {
      colors: {
        background: "transparent",
      },
    };
    
    export default function App() {
      const [user, setUser] = useState(null);
      const [initialRoute, setInitialRoute] = useState("OnBoarding");
    
      const findUser = async () => {
        const result = await AsyncStorage.getItem("user");
        setUser(JSON.parse(result));
        console.log(user);
    
        if (user?.name) {
          setInitialRoute("Home");
        }
      };
    
      useEffect(() => {
        findUser();
      }, []);
    
      if (!user) return null;
    
      return (
        <NavigationContainer theme={navTheme}>
          <Stack.Navigator
            initialRouteName={initialRoute}
            screenOptions={{ headerShown: false }}
          >
            <Stack.Screen name="Onboarding" component={Onboarding} />
            <Stack.Screen name="Onboarding2" component={Onboarding2} />
            <Stack.Screen name="Onboarding3" component={Onboarding3} />
            <Stack.Screen name="Onboarding4" component={Onboarding4} />
            <Stack.Screen name="Onboarding5" component={Onboarding5} />
            <Stack.Screen name="Home" component={Home} />
            <Stack.Screen name="About" component={About} />
            <Stack.Screen name="Name" component={Name} />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
      },
    });
    
    
    
    Login or Signup to reply.
  2. You can do this by adding couple of things to your code . First set a state variable and declare the initial value as follows,

      const [initial, setInitial] = useState("Onboarding"); // Declare the initial state here

    And then , Update the initial state based on the user’s presence

        useEffect(() => {
          if (user.name) {
            setInitial("Home");
          } else {
            setInitial("Onboarding");
          }
        }, [user]);

    Now, the app should correctly determine whether to show the onboarding or home screen based on whether the user’s name exists in the storage.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search