如何在React-Navigation V5中动态显示Drawer项目?

时间:2020-06-01 20:32:40

标签: reactjs react-native react-navigation react-navigation-v5 react-navigation-drawer

尝试在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>
  );

可以帮我弄清楚该错误的解决方法吗?非常感谢!

1 个答案:

答案 0 :(得分:1)

不确定LogOut函数的作用,但是除非它实际上重新运行了效果以便定义了LoginModal屏幕,否则将没有名为LoginModal的屏幕导航到。

查看您的代码,注销后不会重新运行效果。与其设置效果中的屏幕列表,不如将代码安排为以下内容:

  1. Redux,React Context之类的全局存储或您更喜欢存储userId
  2. 的任何存储
  3. useEffect钩子应该还原,像现在一样尝试从userId还原AsyncStorage,但是还原后,它应该更新全局存储以更新{{1 }}而不是设置屏幕
  4. 您的userId函数应从logOut删除userId并更新全局存储,使其为AsyncStorage
  5. 在组件内部,您应根据null是否为userId来有条件地定义屏幕,并且这些屏幕会在登录或注销时自动更改

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

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