React中SessionStorage登录态控制Header登录/注销按钮不实时更新求助
解决方案
问题核心
组件状态未与SessionStorage的变化同步:Headerr组件仅在初始化时读取一次SessionStorage数据,后续SessionStorage更新时组件不会自动重新获取数据;AuthUser工具函数中,保存/清除用户数据时未同步更新对应的React状态,导致组件无法感知状态变化。
具体修改步骤
1. 完善AuthUser工具函数的状态管理
添加dashboard状态变量,在saveDashboard时更新状态,logout时重置所有状态,确保状态与SessionStorage同步:
import axios from 'axios'; import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; export default function AuthUser(){ const navigate = useNavigate(); // 读取SessionStorage数据的工具函数 function getToken (){ const tokenString = sessionStorage.getItem('token'); return JSON.parse(tokenString); } function getEmail (){ const tokenString = sessionStorage.getItem('email'); return JSON.parse(tokenString); } function getUser (){ const userString = sessionStorage.getItem('user'); return JSON.parse(userString); } function getDashboard(){ const dashboardString = sessionStorage.getItem('dashboard'); return JSON.parse(dashboardString); } // 初始化状态 const [token,setToken] = useState(getToken()); const [user,setUser] = useState(getUser()); const [dashboard, setDashboard] = useState(getDashboard()); // 添加dashboard状态 // 保存dashboard并更新状态 const saveDashboard = (userData) => { sessionStorage.setItem('dashboard',JSON.stringify(userData)); setDashboard(userData); // 更新React状态 } // 保存token并更新状态 const saveToken = (user,email,token) =>{ sessionStorage.setItem('token',JSON.stringify(token)); sessionStorage.setItem('user',JSON.stringify(user)); sessionStorage.setItem('email',JSON.stringify(email)); setToken(token); setUser(user); } // 注销时重置所有状态 const logout = () => { sessionStorage.clear(); setToken(null); // 重置token状态 setUser(null); // 重置user状态 setDashboard(null); // 重置dashboard状态 navigate('/'); } // 动态注入最新token的axios实例 const http = axios.create({ baseURL:"http://localhost:8000/api", headers:{ "Content-type" : "application/json", } }); // 请求拦截器:每次请求时自动带上最新token http.interceptors.request.use(config => { const currentToken = getToken(); if(currentToken){ config.headers.Authorization = `Bearer ${currentToken}`; } return config; }); return { setToken:saveToken, token, user, dashboard, // 返回dashboard状态供组件使用 getToken, getEmail, getDashboard, http, logout, saveDashboard, } }
2. 修改Headerr组件,直接使用AuthUser返回的状态
不再自行维护dashboard的useState,直接使用AuthUser提供的状态,确保状态变化时组件自动重新渲染:
function Headerr() { const { dashboard, logout} = AuthUser(); // 直接获取实时状态 const handleLogout = (e) => { logout(); } return ( <> <Row> <Navbar className="bg-body-tertiary navbar border border-1 border-gray navbar-expand navbar-light p-0 "> <Container> <Navbar.Brand href="#home"><img src={logo} alt="Logo" className='logo-width' /></Navbar.Brand> <Navbar.Toggle /> <Navbar.Collapse className="justify-content-end"> <Navbar.Text> {dashboard && ( <> <img src={icon} alt="icon" className='text-dark icon-width '/> <a href="#login" className='text-decoration-none'> {dashboard.dealerName ? dashboard.dealerName.charAt(0).toUpperCase() + dashboard.dealerName.slice(1) : ''} </a> <FontAwesomeIcon style={{cursor:'pointer'}} onClick={handleLogout} icon={faSignOutAlt} className="text-dark fnt-wdth" /> </> )} </Navbar.Text> </Navbar.Collapse> </Container> </Navbar> </Row> </> ); }
3. 登录后同步调用saveDashboard
在登录成功获取dashboard数据的逻辑中,调用saveDashboard方法更新状态,例如登录组件内:
// 登录请求成功后获取到dashboardData const { saveDashboard } = AuthUser(); saveDashboard(dashboardData);
修改说明
- AuthUser统一管理所有用户状态,SessionStorage变化时同步更新React状态,保证组件能实时感知数据变化。
- Headerr组件直接绑定AuthUser返回的状态,状态更新时自动触发组件重渲染,无需手动刷新页面。
- axios拦截器动态获取最新token,避免token更新后请求仍使用旧值的问题。
内容的提问来源于stack exchange,提问作者B L Praveen
相关产品推荐
相关产品推荐

