【发布时间】:2021-02-21 15:16:04
【问题描述】:
我正在开发一个带有登录页面的反应应用程序。当用户成功登录时,后端会返回一个用户对象 (JSON),其中包含一些用户属性(id、用户名、...)以及 JWT 令牌。用户对象存储在 AsyncStorage 中(因此用户只需登录一次)。
try {
await AsyncStorage.setItem('authUser', JSON.stringify(data));
} catch (e) {
console.log(e.message);
}
dispatch({ type: 'SIGN_IN', authUser:data});
状态:
const [state, dispatch] = React.useReducer(
(prevState, action) => {
switch (action.type) {
case 'RESTORE_TOKEN':
return {
...prevState,
authUser: action.authUser,
isLoading: false,
};
case 'SIGN_IN':
return {
...prevState,
isSignout: false,
authUser: action.authUser,
};
case 'SIGN_OUT':
return {
...prevState,
isSignout: true,
authUser: null,
};
}
},
{
isLoading: true,
isSignout: false,
authUser: "",
}
);
我第二次从 AsyncStorage 检索用户对象并将其传递给状态。
try {
authUser = await AsyncStorage.getItem('authUser');
} catch (e) {
console.log(e.message);
}
dispatch({ type: 'RESTORE_TOKEN', authUser: JSON.parse(authUser) });
我使用 UserContext 将authUser 传递到我的欢迎屏幕:
<AuthContext.Provider value={authContext}>
<UserContext.Provider value={{authUser: state.authUser }}>
<NavigationContainer>
<RootStack.Navigator mode="modal" headerMode="none">
{state.isLoading ? (
<RootStack.Screen name="Splash" component={SplashScreen} />
) : state.authUser == null ? (
<RootStack.Screen name="Login" component={AuthenticationStackScreen} />
) : (
<RootStack.Screen name="Home" component={HomeScreen} />
)}
</RootStack.Navigator>
</NavigationContainer>
</UserContext.Provider>
</AuthContext.Provider>
在我的主屏幕中,我打印了一条包含用户名和signOut 按钮的欢迎消息:
function HomeScreen(props) {
const { signOut } = React.useContext(AuthContext);
const { authUser } = React.useContext(UserContext);
return (
<View style={{ flex:1, alignItems: 'center', justifyContent: 'center', backgroundColor:'cyan' }}>
<Text>Hallo {authUser.username}</Text>
<Button title="Log out" onPress={signOut} />
<Text>HomeScreen </Text>
</View>
);
}
当用户登录或已经登录时,主屏幕会以正确的用户名正确显示。单击注销按钮时会出现问题。 authContext 中的 signOut 方法被调用,该方法注销用户并从 AsyncStorage 中删除对象:
signOut: async () => {
try {
await AsyncStorage.removeItem('authUser');
} catch (e) {
console.log(e.message);
}
dispatch({ type: 'SIGN_OUT' })
}
问题:
状态更改为SIGN_OUT,这让我回到了登录页面。但是由于我已经清除了用户对象,所以欢迎通知会引发错误,因为 {authUser.username} 是 null:
TypeError: null is not an object (evaluating 'authUser.username')
我没想到在单击退出按钮时会重新呈现 WelcomeScreen。我是否弄乱了我的应用程序的结构,或者为什么会这样?任何有关如何解决此问题的帮助将不胜感激。提前致谢!
【问题讨论】:
-
只有当 authUser 可用时才能通过访问用户名来处理它{authUser?.username},它可能会重新呈现,因为您有两个不同的上下文提供程序
-
嗨,Guruparan,有没有办法我也可以在 authContext 中传递用户对象?所以我只能使用一个上下文?
-
上下文可以包含任何对象,所以我确信您可以将所有这些信息放入一个对象中并将其放置在上下文中以便它可能
标签: react-native react-context