反应本地登录和登录导航-正确的方式建议 [英] React native login and loggedin navigation - correct way advise

查看:25
本文介绍了反应本地登录和登录导航-正确的方式建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请找人告诉我登录和登录导航系统的正确方式。我现在所做的就是使用共享状态的Use-Better包来使用共享状态,并显示正确的导航。但我不确定这是不是正确的做法。请有人指出正确的方向和正确的方式来实现同样的目标。以下是我的代码。

import React, { useEffect } from "react"; 
import { useLoggedInUserState } from "./core/state"; 
import { useBetween } from "use-between";
import { getLoggedInUser } from "./core/utils";

//navigation
import LoginNav from "./nav/LoginNav";
import LoggedInNav from "./nav/LoggedInNav";

export default function App() {

  //shared states
  const { loggedInUser, setLoggedInUser } = useBetween(useLoggedInUserState);

  //check storage and store user in state
  useEffect(async () => {
    const objUser = await getLoggedInUser();
    setLoggedInUser(objUser);
  }, []);

  //render
  return loggedInUser ? <LoggedInNav loggedInUser={loggedInUser} /> : <LoginNav />;
}

//login nav

已登录导航

import React, { memo } from "react";

import { createDrawerNavigator } from "@react-navigation/drawer";
import { NavigationContainer, CommonActions, useNavigation } from "@react-navigation/native";
import { Appbar, BottomNavigation, Menu, useTheme, Button } from "react-native-paper";
import { Text, Image, View, TouchableOpacity } from "react-native";

import { AboutScreen, TermsScreen, CartScreen, PaymentScreen, NotificationTestScreen, VehicleEditScreen } from "../screens";

import Sidebar from "../components/Sidebar";
import BottomNav from "./BottomNav";

const Drawer = createDrawerNavigator();

//LoggedIn Navigation
const LoggedInNav = (propsLoggedIn) => {
  const { colors, background } = useTheme();

  //const [visible, setVisible] = React.useState(false); //used by appbar
  //const openMenu = () => setVisible(true);  //used by appbar
  //const closeMenu = () => setVisible(false); //used by appbar
  const cartCount = 40; //will be from state

  return (
    <NavigationContainer>
      <Drawer.Navigator
        screenOptions={(propsNavigator) => ({
          headerShown: true,
          headerLeft: () => (
            <View
              style={{
                flex: 1,
                alignItems: "center",
                justifyContent: "center",
                flexDirection: "row",
              }}
            >
              <TouchableOpacity onPress={() => propsNavigator.navigation.openDrawer()}>
                <Image
                  source={require("../assets/images/menu.png")}
                  style={{
                    tintColor: "#fff",
                    width: 28,
                    height: 28,
                    position: "relative",
                    marginLeft: 8,
                  }}
                />
              </TouchableOpacity>

              <TouchableOpacity onPress={() => propsNavigator.navigation.navigate("Dashboard")}>
                <Image
                  source={require("../assets/images/home.png")}
                  style={{
                    tintColor: "#fff",
                    width: 28,
                    height: 28,
                    position: "relative",
                    marginLeft: 8,
                  }}
                />
              </TouchableOpacity>
            </View>
          ),

          headerRight: () => (
            <View
              style={{
                flex: 1,
                alignItems: "center",
                justifyContent: "center",
                flexDirection: "row",
              }}
            >
              <TouchableOpacity
                onPress={() => {
                  propsNavigator.navigation.navigate("NotificationTest");
                }}
              >
                <Image
                  source={require("../assets/images/bell.png")}
                  style={{
                    tintColor: "#fff",
                    width: 32,
                    height: 32,
                    position: "relative",
                    marginRight: 4,
                  }}
                />
              </TouchableOpacity>

              <TouchableOpacity
                onPress={() => {
                  propsNavigator.navigation.navigate("Cart");
                }}
              >
                <Image
                  source={require("../assets/images/cart.png")}
                  style={{
                    tintColor: "#fff",
                    width: 32,
                    height: 32,
                    position: "relative",
                    marginRight: 16,
                  }}
                />
              </TouchableOpacity>
              {cartCount > 0 ? (
                <View
                  style={{
                    position: "absolute",
                    backgroundColor: "red",
                    width: 16,
                    height: 16,
                    borderRadius: 15 / 2,
                    right: 10,
                    top: +8,
                    alignItems: "center",
                    justifyContent: "center",
                  }}
                >
                  <Text
                    style={{
                      alignItems: "center",
                      justifyContent: "center",
                      color: "#FFFFFF",
                      fontSize: 8,
                    }}
                  >
                    {cartCount}
                  </Text>
                </View>
              ) : null}
            </View> 
          ),
          headerStyle: {
            backgroundColor: colors.primary,
          },
          headerTintColor: "#fff",
          headerTitleStyle: {
            fontWeight: "bold",
          },
          /* header using react native paper 
          header: ({ navigation, back, route }) => (
            <Appbar.Header>
              {back ? <Appbar.BackAction onPress={navigation.goBack} /> : null}
              <Appbar.Content title={route.params.title ? route.params.title : "Between Detailing"} />
              {!back ? (
                <Menu visible={visible} onDismiss={closeMenu} anchor={<Appbar.Action icon="menu" color="white" onPress={openMenu} />}>
                  <Menu.Item
                    onPress={() => {
                      navigation.navigate("Dashboard");
                    }}
                    title="Dashboard"
                  />
                  <Menu.Item
                    onPress={() => {
                      navigation.navigate("About");
                    }}
                    title="About"
                  />
                  <Menu.Item
                    onPress={() => {
                      navigation.navigate("Terms");
                    }}
                    title="Terms"
                    //disabled
                  />
                </Menu>
              ) : null}
            </Appbar.Header>
          ),header using react native paper  */
        })}
        drawerContent={(drawerContentProps) => <Sidebar loggedInUser={propsLoggedIn.loggedInUser} {...drawerContentProps} />}
      >
        <Drawer.Screen name="Dashboard" component={BottomNav} initialParams={{ title: "Dashboard" }} />
        <Drawer.Screen name="About" component={AboutScreen} initialParams={{ title: "About" }} />
        <Drawer.Screen name="Terms" component={TermsScreen} initialParams={{ title: "Terms" }} />
        <Drawer.Screen name="VehicleEdit" component={VehicleEditScreen} initialParams={{ title: "Edit Vehicle" }} />
        <Drawer.Screen name="Cart" component={CartScreen} initialParams={{ title: "Cart" }} options={{ drawerItemStyle: { display: "none" } }} />
        <Drawer.Screen name="Payment" component={PaymentScreen} initialParams={{ title: "Payment" }} options={{ drawerItemStyle: { display: "none" } }} />
        <Drawer.Screen name="NotificationTest" component={NotificationTestScreen} initialParams={{ title: "NotificationTest" }} options={{ drawerItemStyle: { display: "none" } }} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

export default memo(LoggedInNav);


谢谢您指向那个链接,我想我的方向差不多是对的。根据这篇文章,我对我的代码做了一些修改,它工作得很好。

我唯一关心的是我在LoginNav和LoggedInNav中都有2个导航容器1,如下所示。对这种情况有什么看法,这样做对吗?

//登录导航

const LoginNav = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        screenOptions={{
          headerShown: false,
        }}
        initialRouteName="Home"
      >
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen name="Register" component={RegisterScreen} />
        <Stack.Screen name="ForgotPassword" component={ForgotPasswordScreen} />
        <Stack.Screen name="Dashboard" component={DashboardScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};  

//登录导航

//LoggedIn Navigation
const LoggedInNav = (propsLoggedIn) => {
  const { colors, background } = useTheme();

  //const [visible, setVisible] = React.useState(false); //used by appbar
  //const openMenu = () => setVisible(true);  //used by appbar
  //const closeMenu = () => setVisible(false); //used by appbar
  const cartCount = 40; //will be from state

  return (
    <NavigationContainer>
      <Drawer.Navigator
         
        drawerContent={(drawerContentProps) => <Sidebar loggedInUser={propsLoggedIn.loggedInUser} {...drawerContentProps} />}
      >
        <Drawer.Screen name="Dashboard" component={BottomNav} initialParams={{ title: "Dashboard" }} />
        <Drawer.Screen name="About" component={AboutScreen} initialParams={{ title: "About" }} />
        <Drawer.Screen name="Terms" component={TermsScreen} initialParams={{ title: "Terms" }} />
        <Drawer.Screen name="VehicleEdit" component={VehicleEditScreen} initialParams={{ title: "Edit Vehicle" }} />
        <Drawer.Screen name="Cart" component={CartScreen} initialParams={{ title: "Cart" }} options={{ drawerItemStyle: { display: "none" } }} />
        <Drawer.Screen name="Payment" component={PaymentScreen} initialParams={{ title: "Payment" }} options={{ drawerItemStyle: { display: "none" } }} />
        <Drawer.Screen name="NotificationTest" component={NotificationTestScreen} initialParams={{ title: "NotificationTest" }} options={{ drawerItemStyle: { display: "none" } }} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

//导航

import LoginNav from "./nav/LoginNav";
import LoggedInNav from "./nav/LoggedInNav";

export default function App() {
  //shared states
  const { loggedInUser, setLoggedInUser } = useBetween(useLoggedInUserState);

  //common states
  const [loading, setLoading] = useState(false);

  //check storage and store user in state
  useEffect(async () => {
    setLoading(true);
    const objUser = await getLoggedInUser();
    setLoggedInUser(objUser);
    setLoading(false);
  }, []);

  //render
  if (!loading) {
    return loggedInUser ? <LoggedInNav loggedInUser={loggedInUser} /> : <LoginNav />;
  } else {
    return (
      <View>
        <Text>Loading...</Text>
      </View>
    );
  }
}

推荐答案

推荐的最佳做法是只有一个NavigationContainer。我认为所有导航状态都有一个真实来源很重要。

尝试如下重构代码:

export default function App() {
  //shared states
  const { loggedInUser, setLoggedInUser } = useBetween(useLoggedInUserState);

  //common states
  const [loading, setLoading] = useState(false);

  //check storage and store user in state
  useEffect(async () => {
    setLoading(true);
    const objUser = await getLoggedInUser();
    setLoggedInUser(objUser);
    setLoading(false);
  }, []);

  //render
  return !loading ? (
    <NavigationContainer>
      {loggedInUser ? (
        <Drawer.Navigator
          drawerContent={(drawerContentProps) => (
            <Sidebar
              loggedInUser={propsLoggedIn.loggedInUser}
              {...drawerContentProps}
            />
          )}
        >
          <Drawer.Screen
            name="Dashboard"
            component={BottomNav}
            initialParams={{ title: "Dashboard" }}
          />
          <Drawer.Screen
            name="About"
            component={AboutScreen}
            initialParams={{ title: "About" }}
          />
          <Drawer.Screen
            name="Terms"
            component={TermsScreen}
            initialParams={{ title: "Terms" }}
          />
          <Drawer.Screen
            name="VehicleEdit"
            component={VehicleEditScreen}
            initialParams={{ title: "Edit Vehicle" }}
          />
          <Drawer.Screen
            name="Cart"
            component={CartScreen}
            initialParams={{ title: "Cart" }}
            options={{ drawerItemStyle: { display: "none" } }}
          />
          <Drawer.Screen
            name="Payment"
            component={PaymentScreen}
            initialParams={{ title: "Payment" }}
            options={{ drawerItemStyle: { display: "none" } }}
          />
          <Drawer.Screen
            name="NotificationTest"
            component={NotificationTestScreen}
            initialParams={{ title: "NotificationTest" }}
            options={{ drawerItemStyle: { display: "none" } }}
          />
        </Drawer.Navigator>
      ) : (
        <Stack.Navigator
          screenOptions={{
            headerShown: false,
          }}
          initialRouteName="Home"
        >
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Login" component={LoginScreen} />
          <Stack.Screen name="Register" component={RegisterScreen} />
          <Stack.Screen
            name="ForgotPassword"
            component={ForgotPasswordScreen}
          />
          <Stack.Screen name="Dashboard" component={DashboardScreen} />
        </Stack.Navigator>
      )}
    </NavigationContainer>
  ) : (
    <View>
      <Text>Loading...</Text>
    </View>
  );
}


这篇关于反应本地登录和登录导航-正确的方式建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆