React刷新登录页面跳转首页:如何先更新状态再渲染组件?
解决React刷新登录权限页面自动跳转首页的问题
问题核心
你的代码存在两个关键问题导致刷新后错误跳转:
loggedIn初始值固定为false,组件首次渲染时会直接基于这个默认值判断,触发跳转逻辑- axios请求是异步操作,你在请求未完成时就读取
sessionStorage,此时拿到的可能是旧值或空值,导致setLoggedIn无法正确更新状态
修复方案
1. 从sessionStorage直接初始化state
组件挂载时优先读取sessionStorage中的auth值作为loggedIn的初始状态,避免渲染阶段使用默认的false判断:
const [loggedIn, setLoggedIn] = useState(() => { // 函数式初始化,只在组件首次挂载时执行一次 const storedAuth = sessionStorage.getItem("auth"); return storedAuth === "true"; });
2. 修正useEffect的异步逻辑
将更新loggedIn的逻辑放在axios请求的then回调内,确保请求完成、sessionStorage更新后再修改状态;同时给useEffect添加空依赖数组,保证只在组件挂载时执行一次:
useEffect(() => { Axios.get("http://localhost:3001/check") .then((response) => { const isAuthorized = response.data["Authorized"]; sessionStorage.setItem('auth', JSON.stringify(isAuthorized)); // 请求成功后同步更新state setLoggedIn(isAuthorized); // 若接口返回用户信息,可在此同步更新user状态 // setUser(response.data.username); }) .catch(() => { // 处理请求失败的情况,统一设置为未登录状态 sessionStorage.setItem('auth', "false"); setLoggedIn(false); }); }, []); // 空依赖数组限制仅执行一次
3. 路由判断逻辑自动生效
现在组件首次渲染时就能拿到正确的初始登录状态,不会再因默认false错误触发跳转。
完整修正后的代码片段
const [loggedIn, setLoggedIn] = useState(() => { const storedAuth = sessionStorage.getItem("auth"); return storedAuth === "true"; }); const [user, setUser] = useState("temp"); Axios.defaults.withCredentials=true; useEffect(() => { Axios.get("http://localhost:3001/check") .then((response) => { const isAuthorized = response.data["Authorized"]; sessionStorage.setItem('auth', JSON.stringify(isAuthorized)); setLoggedIn(isAuthorized); // 示例:从接口返回值更新用户信息 // setUser(response.data.username); }) .catch(() => { sessionStorage.setItem('auth', "false"); setLoggedIn(false); }); }, []); return ( <> {loggedIn ? <LoggedInNavbar user={user} /> : <Navbar/>} <AnimatePresence> <Routes location={location} key={location.pathname}> <Route path="/" element={<Home/>}/> <Route path="/logowanie/:state" element={loggedIn ? <Navigate to="/"/> : <LogIn/>}/> <Route path="/rejestracja" element={loggedIn ? <Navigate to="/"/> : <SignUp/>}/> <Route path="/regulamin" element={<Rules/>}/> <Route path="/dashboard/:username" element={loggedIn ? <Dashboard user={user}/> : <Navigate to="/"/>}/> </Routes> </AnimatePresence> </> );
额外说明
- 使用函数式
useState(() => {})初始化,避免每次组件渲染都重复读取sessionStorage - 必须处理axios请求失败的场景,防止网络错误导致登录状态不一致
- 若需要持久化用户信息,可将用户数据也存入
sessionStorage,初始化时一并读取
内容的提问来源于stack exchange,提问作者user19786344
相关产品推荐
相关产品推荐

