如何在 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 导航到。

查看您的代码,您的效果在您注销后不会重新运行。不要在效果中设置屏幕列表,您应该将代码安排成这样:

  1. 全局存储,如 Redux、React Context 或任何您喜欢存储 userId
  2. useEffect 挂钩应该恢复 尝试像您现在所做的那样从 AsyncStorage 恢复 userId,但恢复后,它应该更新您的全局存储以更新 userId 在那里而不是设置屏幕
  3. 您的 logOut 函数应该从 AsyncStorage 中删除 userId 并更新全局存储,使其成为 null.
  4. 在您的组件中,您应该根据 userId 是否 null 有条件地定义屏幕,并且它们会在登录或注销时自动更改

身份验证流程的文档显示了使用令牌和堆栈导航器如何工作的示例:https://reactnavigation.org/docs/auth-flow/

您可以对用户 ID 和抽屉导航器使用类似的策略。