如何在 React-Navigation V5 中动态显示抽屉项目?
How to dynamically show Drawer items in React-Navigation V5?
我在尝试在 React-Navigation 抽屉中动态显示不同项目时遇到了一些麻烦。
我有一个抽屉,需要在用户登录或未登录时显示不同的项目。在这种情况下,如果用户已登录,则不应显示 "RegisterScreen" 和 "LoginScreen" 按钮,而应显示 "Log Out" 按钮。但是,如果用户未登录,则应同时显示注册和登录屏幕,而不会显示注销按钮。
我已经使用下面的代码成功显示了按钮(除了注销按钮,我还没有这样做)。但是,一旦用户注销,应用程序会将他们重定向到登录屏幕。由于我没有在抽屉中声明它们,因此出现以下错误:
console.error: The action 'NAVIGATE' with payload {"name":"LoginModal"} was not handled by any navigator.
我知道没有添加屏幕,但我不知道如何在用户登录时隐藏它们。
代码:
//Added DrawerItemList for the Logout button.
const CustomDrawerContent = (props) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem
label="Logout"
onPress={async () => {
props.navigation.closeDrawer();
await LogOut().then((result) => {
props.navigation.navigate('LoginModal');
});
}}
/>
</DrawerContentScrollView>
);
};
const [drawerCategories, setDrawerCategories] = useState([]);
//Checks if the user is logged in and sets Login and Register screens in the state.
useEffect(() => {
let mounted = true;
if (mounted) {
AsyncStorage.getItem('userId').then((result) => {
console.log(result);
if (result == null) {
setDrawerCategories([
...drawerCategories,
{name: 'LoginModal', component: {LoginScreen}},
{name: 'RegisterModal', component: {RegisterScreen}},
]);
}
});
}
return () => (mounted = false);
}, []);
return (
<NavigationContainer>
<RootDrawer.Navigator
drawerType="front"
initialRouteName="Home"
mode="modal"
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<RootDrawer.Screen name="Home" component={MainStackScreen} />
//Add the Register and Login buttons here
{drawerCategories.map((drawer) => {
<RootDrawer.Screen name={drawer.name} component={drawer.component} />;
})}
</RootDrawer.Navigator>
</NavigationContainer>
);
你能帮我弄清楚如何解决这个错误吗?太感谢了!
不确定您的 LogOut
功能的作用,但除非它实际上重新 运行 效果以便定义您的 LoginModal
屏幕,否则不会有屏幕命名为 LoginModal
导航到。
查看您的代码,您的效果在您注销后不会重新运行。不要在效果中设置屏幕列表,您应该将代码安排成这样:
- 全局存储,如 Redux、React Context 或任何您喜欢存储
userId
useEffect
挂钩应该恢复 尝试像您现在所做的那样从 AsyncStorage
恢复 userId
,但恢复后,它应该更新您的全局存储以更新 userId
在那里而不是设置屏幕
- 您的
logOut
函数应该从 AsyncStorage
中删除 userId
并更新全局存储,使其成为 null
.
- 在您的组件中,您应该根据
userId
是否 null
有条件地定义屏幕,并且它们会在登录或注销时自动更改
身份验证流程的文档显示了使用令牌和堆栈导航器如何工作的示例:https://reactnavigation.org/docs/auth-flow/
您可以对用户 ID 和抽屉导航器使用类似的策略。
我在尝试在 React-Navigation 抽屉中动态显示不同项目时遇到了一些麻烦。
我有一个抽屉,需要在用户登录或未登录时显示不同的项目。在这种情况下,如果用户已登录,则不应显示 "RegisterScreen" 和 "LoginScreen" 按钮,而应显示 "Log Out" 按钮。但是,如果用户未登录,则应同时显示注册和登录屏幕,而不会显示注销按钮。
我已经使用下面的代码成功显示了按钮(除了注销按钮,我还没有这样做)。但是,一旦用户注销,应用程序会将他们重定向到登录屏幕。由于我没有在抽屉中声明它们,因此出现以下错误:
console.error: The action 'NAVIGATE' with payload {"name":"LoginModal"} was not handled by any navigator.
我知道没有添加屏幕,但我不知道如何在用户登录时隐藏它们。
代码:
//Added DrawerItemList for the Logout button.
const CustomDrawerContent = (props) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem
label="Logout"
onPress={async () => {
props.navigation.closeDrawer();
await LogOut().then((result) => {
props.navigation.navigate('LoginModal');
});
}}
/>
</DrawerContentScrollView>
);
};
const [drawerCategories, setDrawerCategories] = useState([]);
//Checks if the user is logged in and sets Login and Register screens in the state.
useEffect(() => {
let mounted = true;
if (mounted) {
AsyncStorage.getItem('userId').then((result) => {
console.log(result);
if (result == null) {
setDrawerCategories([
...drawerCategories,
{name: 'LoginModal', component: {LoginScreen}},
{name: 'RegisterModal', component: {RegisterScreen}},
]);
}
});
}
return () => (mounted = false);
}, []);
return (
<NavigationContainer>
<RootDrawer.Navigator
drawerType="front"
initialRouteName="Home"
mode="modal"
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<RootDrawer.Screen name="Home" component={MainStackScreen} />
//Add the Register and Login buttons here
{drawerCategories.map((drawer) => {
<RootDrawer.Screen name={drawer.name} component={drawer.component} />;
})}
</RootDrawer.Navigator>
</NavigationContainer>
);
你能帮我弄清楚如何解决这个错误吗?太感谢了!
不确定您的 LogOut
功能的作用,但除非它实际上重新 运行 效果以便定义您的 LoginModal
屏幕,否则不会有屏幕命名为 LoginModal
导航到。
查看您的代码,您的效果在您注销后不会重新运行。不要在效果中设置屏幕列表,您应该将代码安排成这样:
- 全局存储,如 Redux、React Context 或任何您喜欢存储
userId
useEffect
挂钩应该恢复 尝试像您现在所做的那样从AsyncStorage
恢复userId
,但恢复后,它应该更新您的全局存储以更新userId
在那里而不是设置屏幕- 您的
logOut
函数应该从AsyncStorage
中删除userId
并更新全局存储,使其成为null
. - 在您的组件中,您应该根据
userId
是否null
有条件地定义屏幕,并且它们会在登录或注销时自动更改
身份验证流程的文档显示了使用令牌和堆栈导航器如何工作的示例:https://reactnavigation.org/docs/auth-flow/
您可以对用户 ID 和抽屉导航器使用类似的策略。