我有以下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);
您的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