React JS使用redux-react-session维护会话的方法及可运行示例
redux-react-session 生产可用实现示例
以下是经过验证可直接运行的接入流程,覆盖会话存储、登录登出、路由鉴权全流程,附高频踩坑说明。
1. 安装依赖
先安装必需的npm包:
npm install redux react-redux redux-thunk redux-react-session
2. Redux Store配置
核心注意:必须将包提供的sessionReducer挂载到store的session根字段下,这是绝大多数人调试失败的首要原因,包内部逻辑写死读取该路径下的状态
// src/store/index.js import { createStore, combineReducers, applyMiddleware } from 'redux'; import { thunk } from 'redux-thunk'; import { sessionReducer, sessionService } from 'redux-react-session'; // 合并根reducer,session字段不可改名、不可嵌套到其他层级 const rootReducer = combineReducers({ session: sessionReducer, // 其他业务reducer可在下方追加,例如: user: userReducer }); const store = createStore( rootReducer, applyMiddleware(thunk) // 必须注册thunk中间件,包内异步action依赖该能力 ); // 初始化会话服务 sessionService.initSessionService(store, { driver: 'LOCALSTORAGE', // 存储介质,支持LOCALSTORAGE/SESSIONSTORAGE/COOKIES expiresIn: 7 * 24 * 60 * 60, // 会话有效期,单位秒,此处配置为7天 refreshOnCheckAuth: false, // 鉴权时是否强制刷新页面,单页应用建议设为false }); export default store;
3. 根组件注入Store
在应用入口文件注入Redux Store:
// src/main.jsx (React18入口) import React from 'react'; import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux'; import store from './store'; import App from './App'; ReactDOM.createRoot(document.getElementById('root')).render( <Provider store={store}> <App /> </Provider> );
4. 业务场景使用示例
登录后保存会话
接口返回登录成功后,调用服务方法保存token和用户信息:// src/pages/Login.jsx import { useState } from 'react'; import { sessionService } from 'redux-react-session'; export default function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const submitLogin = async () => { // 替换为自身业务的登录接口请求 const loginRes = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }).then(res => res.json()); if (loginRes.code === 0) { // 保存会话token,传入对象必须包含token字段,否则不会标记为已登录 await sessionService.saveSession({ token: loginRes.data.token }); // 保存用户基础信息 await sessionService.saveUser(loginRes.data.userInfo); // 跳转至业务首页 window.location.replace('/dashboard'); } }; return ( <div className="login-form"> <input value={username} onInput={e => setUsername(e.target.value)} placeholder="用户名" /> <input type="password" value={password} onInput={e => setPassword(e.target.value)} placeholder="密码" /> <button onClick={submitLogin}>登录</button> </div> ); }路由鉴权拦截
封装路由守卫组件,校验未登录直接跳转登录页:// src/components/AuthGuard.jsx import { useEffect } from 'react'; import { useSelector } from 'react-redux'; export default function AuthGuard({ children }) { // 从session字段读取鉴权状态 const { authenticated, checked } = useSelector(state => state.session); useEffect(() => { if (!checked) return; if (!authenticated) window.location.replace('/login'); }, [authenticated, checked]); // 会话状态校验未完成时显示加载态 if (!checked) return <div>页面加载中...</div>; return authenticated ? children : null; }读取登录用户信息
直接从Redux状态中读取即可:import { useSelector } from 'react-redux'; // 组件内调用 const currentUser = useSelector(state => state.session.user); const currentToken = useSelector(state => state.session.session.token);登出清空会话
调用deleteSession方法清空本地存储的会话信息:import { sessionService } from 'redux-react-session'; const handleLogout = async () => { await sessionService.deleteSession(); window.location.replace('/login'); };
高频踩坑汇总
- 不要修改sessionReducer的挂载路径,必须放在根state的session字段下,否则所有逻辑失效
- saveSession方法传入的参数必须包含token属性,包内部默认校验该字段存在才会将authenticated设为true
- 必须注册redux-thunk中间件,否则包内的异步action无法正常执行
- initSessionService必须在store创建完成后立即调用,且要传入store实例,否则服务无法绑定状态流
内容的提问来源于stack exchange,提问作者Nitesh Sawant
相关产品推荐
相关产品推荐

