我有一个反应本机应用程序,它将登录凭据存储在 jwt 中。我的注销功能如下所示:
logOut={() => {
AsyncStorage.getAllKeys()
.then((keys) => AsyncStorage.multiRemove(keys))
.then(() =>
navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
key: null,
}),
)
我的 StackNavigator(在 App.jsx 中)如下所示:
<NavigationContainer >
<Stack.Navigator>
{valid_token ? (
consented ? (
<>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Nav" component={Nav} /> // Nav is the component with the login function
</>
): (
<>
<Stack.Screen name="ConsentForm" component={ConsentForm} />
</>
)
) : (
<>
<Stack.Screen name='Login'>
{(props) => <Login setExpired={setValidToken} setConsented={setConsented} />}
</Stack.Screen>
</>
)}
</Stack.Navigator>
</NavigationContainer>
valid_token
是根据异步存储中的jwt的值设置的。我正在清除注销函数中的令牌,但是 App.jsx 没有看到这一点。我也不确定我是否真的必须在整个应用程序中传递 setValidToken
和 setConsented
道具(包含注销的导航栏位于每个屏幕上)。当我不传递 props 并按原样运行代码时,我收到此错误:
The action 'RESET' with payload {"index":0,"routes":[{"name":"Login"}],"key":null} was not handled by any navigator.
我尝试用
navigation.reset
替换注销功能的 navigation.dispatch(StackActions.popToTop())
部分 - 这会将我带到主页。
在整个应用程序中传递道具是我唯一的选择吗?
您面临的问题是在 React Native 中处理身份验证和导航时的常见问题。出现问题的原因是,从 AsyncStorage 中删除令牌时,导航状态并未更新。这里有一些建议:
集中您的身份验证状态:不要在整个应用程序中传递
setValidToken
和 setConsented
属性,请考虑使用集中式状态管理解决方案,例如 Redux 或 React 的 Context API。这样,您可以从应用程序中的任何位置更新身份验证状态,并立即在任何地方反映出来。
使用身份验证流程:考虑按照 React 导航文档中的建议设置身份验证流程。这涉及到为身份验证相关屏幕(如登录)创建一个单独的堆栈导航器,并为主应用程序屏幕创建另一个堆栈导航器。然后,您可以根据您的身份验证状态有条件地渲染其中之一。
正确重置导航状态:错误消息表明,当您尝试重置导航器时,导航器中不存在“登录”路线。确保您在导航操作中使用的路线名称与您的
name
组件的 Screen
属性相对应。
以下是如何设置导航器的示例:
// AuthNavigator
const AuthNavigator = createStackNavigator();
<AuthNavigator.Navigator>
<AuthNavigator.Screen name="Login" component={Login} />
</AuthNavigator.Navigator>
// AppNavigator
const AppNavigator = createStackNavigator();
<AppNavigator.Navigator>
<AppNavigator.Screen name="Home" component={Home} />
<AppNavigator.Screen name="Nav" component={Nav} />
</AppNavigator.Navigator>
// RootNavigator
const RootNavigator = () => {
const isLoggedIn = // get this from your state
return (
<NavigationContainer>
{isLoggedIn ? <AppNavigator /> : <AuthNavigator />}
</NavigationContainer>
);
};
在注销功能中,您将重置到“登录”屏幕,如下所示:
navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
这应该正确重置导航状态并带您返回登录屏幕。请记住将
createStackNavigator
替换为您使用的任何类型的导航器(例如 createStackNavigator
、createBottomTabNavigator
等)