Home > Mobile >  Show Onboarding screen once
Show Onboarding screen once

Time:10-31

Does anyone know where I have gone wrong here? I am trying to dispatch an action when the user taps a button that calls the onSkip function, In the reducer I set the item to local storage and I retrieve it in the rootstack component so I can conditionally set the initial screen in my stack navigator. It always returns false and goes to the onboarding screen instead of login screen.

import React, { useEffect } from 'react'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { RootStackParamList } from '../interfaces/RootStackParamList'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { theme } from '../themes/themes'
import { useAppSelector } from '../app/hooks'

import DrawerNav from './DrawerNav'
import Tabs from './Tabs'
import HomeScreen from '../screens/HomeScreen'
import Login from '../screens/Auth/Login'
import OnboardingScreen from '../screens/Onboarding/OnboardingScreen'
import OtpScreen from '../screens/Auth/OtpScreen'

function RootStack() {
    const Stack = createNativeStackNavigator<RootStackParamList>()
    const onboardingState = useAppSelector(
        (state) => state.onboarding.viewedOnBoarding
    )
    const [onboarded, setOnboarded] = React.useState(false)

    const checkOnboarding = async () => {
        try {
            const value = await AsyncStorage.getItem('@onBoarding')
            if (value !== null) {
                setOnboarded(true)
            }
        } catch (err) {
        } finally {
        }
    }
    useEffect(() => {
        checkOnboarding()
    }, [])

    return (
        <NavigationContainer>
            <Stack.Navigator
                initialRouteName={
                    onboarded === true ? 'Login' : 'OnboardingScreen'
                }
                screenOptions={{
                    headerShown: false,
                }}
            >
                <Stack.Screen options={{}} name='Login' component={Login} />
                <Stack.Screen
                    name='OnboardingScreen'
                    component={OnboardingScreen}
                />
                <Stack.Screen name='Tabs' component={Tabs} />
                <Stack.Screen name='DrawerNav' component={DrawerNav} />
                <Stack.Screen
                    name='OtpScreen'
                    component={OtpScreen}
                    options={{
                        title: 'OTP',
                        headerShown: true,
                        headerStyle: {
                            backgroundColor: theme.colors.whiteSmoke,
                        },
                    }}
                />
            </Stack.Navigator>
        </NavigationContainer>
    )
}
export default RootStack 
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import AsyncStorage from '@react-native-async-storage/async-storage'

export interface onboardingState {
    viewedOnBoarding: boolean
}

const initialState: onboardingState = {
    viewedOnBoarding: false,
}

export const onboardingSlice = createSlice({
    name: 'onboarding',
    initialState,
    reducers: {
        setOnboardingAsync: (state, action: PayloadAction<boolean>) => {
            state.viewedOnBoarding = action.payload
            AsyncStorage.setItem('@onBoarding', JSON.stringify(action.payload))
        },
    },
})

// Action creators are generated for each case reducer function
export const { setOnboardingAsync } = onboardingSlice.actions

export default onboardingSlice.reducer

onSkip={() => (
    dispatch(setOnboardingAsync(true)),
    navigation.replace('Login'),
    AsyncStorage.setItem('@onBoarding', JSON.stringify(true))
)}

CodePudding user response:

If you want to persist user's onboarding status, just use Redux-persist in your project (no need to directly use AsyncStorage).

After you implemented redux-persist, just use the

const onboardingState = useAppSelector((state) => state.onboarding.viewedOnBoarding)

to check whether user is onboarded.

  • Related