【问题标题】:Show Onboarding screen once显示一次入职屏幕
【发布时间】:2021-12-15 02:06:58
【问题描述】:

有人知道我哪里出错了吗? 当用户点击调用 onSkip 函数的按钮时,我试图调度一个动作,在减速器中,我将项目设置为本地存储,并在 rootstack 组件中检索它,以便有条件地在堆栈导航器中设置初始屏幕。它总是返回 false 并转到入职屏幕而不是登录屏幕。

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))
)}

【问题讨论】:

    标签: react-native navigation redux-toolkit asyncstorage


    【解决方案1】:

    如果要保持用户的入职状态,只需在项目中使用Redux-persist即可(无需直接使用AsyncStorage)。

    实现 redux-persist 后,只需使用

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

    检查用户是否登录。

    【讨论】:

    • 我会试试的。
    • 使用 redux-persist 确实对我有用。
    猜你喜欢
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 2015-08-07
    • 1970-01-01
    相关资源
    最近更新 更多