React Native Web页面刷新后保持登录状态的实现方法
解决Expo React Native Web页面刷新后Token丢失的问题
问题根源很明确:页面刷新后React组件重新初始化,你的AuthContext里的user状态被重置为null,且未在组件挂载时从AsyncStorage读取之前保存的Token、恢复登录状态。
修复步骤:
1. 在认证上下文初始化时读取并恢复登录状态
修改AuthContextProvider,添加组件挂载逻辑,从AsyncStorage读取Token并验证有效性(可选但推荐),同步更新用户状态:
import { AccountRequest, AccountUpdateRequest, loginRequest, logoutRequest, registerRequest, } from "./authentication.service"; import React, { createContext, useState, useEffect } from "react"; import AsyncStorage from '@react-native-async-storage/async-storage'; export const AuthContext = createContext(); export const AuthContextProvider = ({ children }) => { const [isLoading, setIsLoading] = useState(true); // 初始为true,处理初始化加载 const [error, setError] = useState(null); const [user, setUser] = useState(null); // 组件挂载时检查登录状态 useEffect(() => { const checkAuthStatus = async () => { try { const savedToken = await AsyncStorage.getItem("Token"); if (savedToken) { // 可选:调用后端接口验证Token有效性(比如获取用户信息) // const response = await fetch(`${API_URL}/api/user/profile/`, { // headers: { "Authorization": `Bearer ${savedToken}` } // }); // if (response.ok) { // const userData = await response.json(); // setUser(userData); // 用真实用户信息更新状态 // } else { // await AsyncStorage.removeItem("Token"); // Token无效则清除 // } // 若暂时无验证接口,先将user设为true(匹配当前loginRequest返回值) setUser(true); } } catch (err) { console.error("读取登录状态失败:", err); await AsyncStorage.removeItem("Token"); // 读取失败时清除无效Token } finally { setIsLoading(false); // 初始化完成 } }; checkAuthStatus(); }, []); const onLogin = (email, password) => { setIsLoading(true); loginRequest(email, password) .then((u) => { setUser(u); setIsLoading(false); }) .catch((e) => { setIsLoading(false); setError(e.toString()); }); }; // 补充登出逻辑,确保清除Token const onLogout = async () => { try { await logoutRequest(); await AsyncStorage.removeItem("Token"); setUser(null); } catch (err) { console.error("登出失败:", err); setError(err.toString()); } }; return ( <AuthContext.Provider value={{ isAuthenticated: !!user, isLoading, error, user, onLogin, onRegister, onLogout, handleValidEmail, handleValidPassword, UserProfileRequest, UpdateUserProfileRequest, }}> {!isLoading && children} {/* 初始化完成后再渲染子组件,避免页面闪烁 */} </AuthContext.Provider> ); };
2. 优化登录请求返回值(可选)
当前loginRequest返回true,建议改为返回用户信息(若后端接口提供),让user状态存储真实用户数据:
export const loginRequest = async (email, password) => { try { const response = await fetch(`${API_URL}/api/user/token/`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email, password }), }); const data = await response.json(); if (response.ok) { await AsyncStorage.setItem("Token", data.token); // 若后端返回用户信息,直接返回 // return data.user; // 否则返回含token的对象,方便后续使用 return { token: data.token }; } else { throw new Error(data.detail || "邮箱或密码错误"); } } catch (error) { console.error("登录失败:", error); throw new Error("邮箱或密码输入错误"); } };
关键说明:
- 组件挂载时通过
useEffect读取AsyncStorage中的Token,是刷新页面后恢复登录状态的核心。 - 验证Token有效性的步骤能避免使用过期/无效Token访问接口,提升安全性。
- 登出时必须清除
AsyncStorage中的Token,确保状态同步。
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

