使用 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 语句中。
我是 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 语句中。