使用 useEffect 的 Stack navigator React 导航验证流程

Stack navigator React navigation auth flow using useEffect

我是 React Native 的新手,我尝试使用 React Navigation 在登录和主屏幕之间导航来实现一个简单的登录。但是,当以前的用户信用存储在 asyncStorage 中时,我无法弄清楚如何让用户回到家,而当 asyncStorage 中没有存储信用时如何进入登录屏幕。即使我已登录,我仍然会进入登录屏幕。我尝试搜索、复制、修改我在互联网上找到的任何示例,但其中 none 满足我的需要,更不用说每个示例都使用 React导航版本 4.xx 及以下。我怎样才能做到这一点,这样我就可以为我的 React Native 项目中的所有其他代码实现它们。也许我遗漏了什么或写错了什么?任何帮助表示赞赏。启动画面 setTimeOut 似乎也不起作用。

流程应该是:

启动画面 -> isLogin? -> 首页

Splash Screen -> 是不是登录? -> 登录屏幕

但我不断得到

启动画面(眨眼间)-> 登录画面

无论我是否登录

这是我的App.js

import 'react-native-gesture-handler';
import React, {Component, useEffect, useReducer} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

import {loadUser} from './src/util/userStorage';
import LoginFunct from './src/loginFunct';
import Home from './src/home';
import SplashScreen from './src/splashScreen';

const Stack = createStackNavigator();

function App({navigation}) {
  const [state, dispatch] = useReducer(
    (prevState, action) => {
      switch (action.type) {
        case 'FETCH_CREDS':
          return {
            ...prevState,
            user: action.user,
            loading: false,
            isLogin: action.isLogin,
          };
      }
    },
    {
      loading: true,
      isLogin: false,
      user: {},
    },
  );

  useEffect(() => {
    const fetchData = () => {
      let userData;
      let loggedIn;
      try {
        // setTimeout(() => {
        loadUser().then((data) => {
          if (data) {
            console.log(data);
            userData = data;
            loggedIn = true;
          }
        });
        // }, 2000);
      } catch (e) {
        console.log(e);
      }
      dispatch({
        type: 'FETCH_CREDS',
        user: userData,
        loading: false,
        isLogin: loggedIn,
      });
    };
    fetchData();
  }, []);

  return (
    <NavigationContainer>
      <Stack.Navigator>
        {!state.loading ? (
          state.isLogin ? (
            <>
            {console.log(state.isLogin)}
            <Stack.Screen
              name="Home"
              component={Home}
              options={{
                title: 'Home',
              }}
            />
            <Stack.Screen
              name="LoginFunct"
              component={LoginFunct}
              options={{
                title: 'Sign In',
              }}
            />
            </>
          ) : (
            <>
            {console.log(state.isLogin)}
            <Stack.Screen
              name="LoginFunct"
              component={LoginFunct}
              options={{
                title: 'Sign In',
              }}
            />
            <Stack.Screen
              name="Home"
              component={Home}
              options={{
                title: 'Home',
              }}
            />
            </>
          )
        ) : (
          <Stack.Screen name="SplashScreen" component={SplashScreen} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}
export default App;

这是我的 userStorage,其中 loadUser 是

import AsyncStorage from '@react-native-async-storage/async-storage';

const STORAGE_KEY = 'USER';

export const loadUser = async () => {
  try {
    const data = await AsyncStorage.getItem(STORAGE_KEY);
    if (data !== null) {
      return data;
    }
  } catch (error) {
    console.log('Error user loading', error);
  }
};

export const saveUser = async (data) => {
  try {
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(data));
  } catch (error) {
    console.log(error);
  }
};

export const clearUser = async () => {
  try {
    await AsyncStorage.clear();
  } catch (error) {
    console.log(error);
  }
};

你的抓取和异步存储都是异步的。

尝试使用此方法,将其转换为异步函数并使用 await。这允许在异步函数完成后调用您的调度。

useEffect(() => {

const fetchData = async() => {
      let userData;
      let loggedIn;
      try {
        // setTimeout(() => {
        await loadUser().then((data) => {
          if (data) {
            console.log(data);
            userData = data;
            loggedIn = true;
          }
        });
        // }, 2000);

      dispatch({
        type: 'FETCH_CREDS',
        user: userData,
        loading: false,
        isLogin: loggedIn,
      });
      } catch (e) {
        console.log(e);
      }

    };
      fetchData();
},[])

Using Async and Await for asynchronous operations

或者,将您的调度语句放在 then 语句中。