在登录屏幕中将AsyncStorage与React Navigation 5一起使用

问题描述 投票:0回答:1

我有以下JSX,它当前正在使用Redux状态来获取用户令牌,但是问题是,如果重新加载应用程序,状态将丢失。我想创建一个登录屏幕并使用AsyncStorage进行存储,但是从AsyncStorage检索数据后,似乎无法刷新页面。我已经尝试了所有方法,但无法使它正常工作。这是我的正在使用Redux存储的AuthLoading.js文件:

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { createStackNavigator } from "@react-navigation/stack";
import { NavigationContainer } from "@react-navigation/native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { Ionicons } from "@expo/vector-icons";
import { AsyncStorage } from "react-native";
import { useDispatch } from "react-redux";

import * as authActions from "../store/actions/auth";

import ProductsOverViewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetailsScreen from "../screens/shop/ProductDetailsScreen";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
import UserProductScreen from "../screens/user/UserProductsScreen";
import EditProductsScreen from "../screens/user/EditProductsScreen";
import AuthScreen from "../screens/user/AuthScreen";
import Colours from "../constants/Colours";

function AuthLoading({ user }) {
  const [userToken, setUserToken] = useState(null);
  const dispatch = useDispatch();

  const onTokenChange = (value) => {
    setUserToken(value);
  };

  useEffect(() => {
    const tryLogin = async () => {
    //   AsyncStorage.removeItem("userData");
      const userData = await AsyncStorage.getItem("userData");
      if (!userData) {
        console.log("userData");
        console.log(userData);
        // props.navigation.navigate("Auth");
        return;
      }
      const transformedData = JSON.parse(userData);
      const { token, userId, expiryDate } = transformedData;
      const expirationDate = new Date(expiryDate);

      if (expirationDate <= new Date() || !token || !userId) {
        // props.navigation.navigate("Auth");
        return;
      }
      onTokenChange(token);
      //   props.navigation.navigate("Shop");
      dispatch(authActions.authenticate(userId, token));
    };

    tryLogin();
  }, [dispatch]);

  //   useEffect(() => {
  //     console.log("user token updated: " + user.token);
  //     onTokenChange(user.token);
  //   }, [user.token]);

  const AuthStack = createStackNavigator();
  const DrawerNavigator = createDrawerNavigator();

  function DrawerNavigation() {
    return (
      //   <NavigationContainer>
      <DrawerNavigator.Navigator
        drawerContentOptions={{
          activeTintColor: Colours.primary,
          labelStyle: {
            fontFamily: "open-sans",
          },
        }}
        // initialRouteName="Auth"
        screenOptions={({ route }) => ({
          headerTintColor: "white",
          headerStyle: { backgroundColor: Colours.PrimaryColour },
          drawerIcon: ({ focused, color, size }) => {
            let iconName;

            if (route.name === "Products") {
              iconName = "md-list";
            } else if (route.name === "Orders") {
              iconName = "md-cart";
            } else if (route.name === "Admin") {
              iconName = "md-create";
            }
            // You can return any component that you like here!
            return <Ionicons name={iconName} size={25} color={color} />;
          },
        })}
      >
        <DrawerNavigator.Screen name="Products" component={StackScreen} />
        <DrawerNavigator.Screen name="Orders" component={OrdersStackScreen} />
        <DrawerNavigator.Screen
          name="Admin"
          component={UserProductStackScreen}
        />
      </DrawerNavigator.Navigator>
      //   </NavigationContainer>
    );
  }

  const Stack = createStackNavigator();

  const OrdersStack = createStackNavigator();

  function OrdersStackScreen() {
    return (
      <OrdersStack.Navigator
        screenOptions={{
          headerTintColor: "white",
          headerStyle: {
            backgroundColor: Colours.primary,
          },
          headerTitleStyle: {
            fontFamily: "open-sans",
          },
        }}
      >
        <OrdersStack.Screen name="Orders" component={OrdersScreen} />
      </OrdersStack.Navigator>
    );
  }

  const EditStack = createStackNavigator();

  function EditStackScreen() {
    return (
      <EditStack.Navigator
        screenOptions={{
          headerTintColor: "white",
          headerStyle: {
            backgroundColor: Colours.primary,
          },
          headerTitleStyle: {
            fontFamily: "open-sans",
          },
        }}
      >
        <EditStack.Screen name="Orders" component={EditProductsScreen} />
      </EditStack.Navigator>
    );
  }

  const UserProductStack = createStackNavigator();

  function UserProductStackScreen() {
    return (
      <UserProductStack.Navigator
        screenOptions={{
          headerTintColor: "white",
          headerStyle: {
            backgroundColor: Colours.primary,
          },
          headerTitleStyle: {
            fontFamily: "open-sans",
          },
        }}
      >
        <UserProductStack.Screen name="Admin" component={UserProductScreen} />
      </UserProductStack.Navigator>
    );
  }

  function StackScreen() {
    return (
      <Stack.Navigator
        screenOptions={{
          headerTintColor: "white",
          //   header: () => null,
          headerStyle: {
            backgroundColor: Colours.primary,
          },
          headerTitleStyle: {
            fontFamily: "open-sans",
          },
          // headerTitle: "Authentication",
        }}
      >
        <Stack.Screen
          name="Products Over View"
          component={ProductsOverViewScreen}
        />
        <Stack.Screen
          name="ProductDetailsScreen"
          component={ProductDetailsScreen}
        />

        <Stack.Screen name="Cart" component={CartScreen} />
        <Stack.Screen name="Admin" component={UserProductScreen} />
        <Stack.Screen name="Edit" component={EditProductsScreen} />
      </Stack.Navigator>
    );
  }

  return (
    <NavigationContainer>
      <Stack.Navigator
        screenOptions={{
          header: () => null,
        }}
      >
        {userToken ? (
          <Stack.Screen name="Home" component={DrawerNavigation} />
        ) : (
          <Stack.Screen name="SignIn" component={AuthScreen} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

const mapStatetoProps = (state) => ({
  user: state.auth,
});

export default connect(mapStatetoProps, null)(AuthLoading);

react-native react-navigation
1个回答
0
投票

您的useEffect挂钩具有dispatch作为依赖项。如果希望它在组件渲染时运行,则应为依赖项使用一个空列表:[]

  useEffect(() => {
    const tryLogin = async () => {
    //   AsyncStorage.removeItem("userData");
      const userData = await AsyncStorage.getItem("userData");
      if (!userData) {
        console.log("userData");
        console.log(userData);
        // props.navigation.navigate("Auth");
        return;
      }
      const transformedData = JSON.parse(userData);
      const { token, userId, expiryDate } = transformedData;
      const expirationDate = new Date(expiryDate);

      if (expirationDate <= new Date() || !token || !userId) {
        // props.navigation.navigate("Auth");
        return;
      }
      onTokenChange(token);
      //   props.navigation.navigate("Shop");
      dispatch(authActions.authenticate(userId, token));
    };

    tryLogin();
  }, []); // <------ this is all I changed
© www.soinside.com 2019 - 2024. All rights reserved.