react中使用Redux管理token以及token持久化

avatar
作者
筋斗云
阅读量:0

1.安装插件

npm i @reduxjs/toolkit react-redux

2.新建状态管理文件

在src下新建store文件夹,store文件夹下新建模块文件夹(modules)和入口文件(index.js),modules文件夹下新建setToken.js文件

3.配置setToken.js

import { createSlice } from "@reduxjs/toolkit"; import axios from 'axios'  const tokenStore = createSlice({     name: 'setToken',     initialState: {         token: ''     },     reducers: {         setToken(state, actions) {             state.token = actions.payload         }     } })  const { setToken } = tokenStore.actions; const tokenStoreReducer = tokenStore.reducer;  // 异步请求 function login(data){     return (dispatch)=>{         axios.get('http://localhost:8888/token').then(res=>{             dispatch(setToken(res.data))         })     } }  export { setToken,login } export default tokenStoreReducer

4.注册setToken模块

src/store/index.js

// store/index.js该文件为状态管理的入口文件 // configureStore用于创建store实例 import { configureStore } from "@reduxjs/toolkit";  // 导入子模块reducer,用于注册子模块 import tokenStoreReducer from "./modules/setToken";  const store = configureStore({     reducer:{ // 注册子模块的地方,可以注册多个子模块         token:tokenStoreReducer     } })  export default store

5.挂载store

src/App.js

// 该文件为主组件 import store from './store'; import { Provider } from 'react-redux';  import router from './router'; import { RouterProvider } from 'react-router-dom'  function App() {   return (     <RouterProvider router={router}>       <Provider store={store}></Provider>     </RouterProvider>   ); }  export default App; 

6.登录页面调用状态管理中的异步请求获取token

import { Button, Checkbox, Form, Input, Card } from 'antd'; import './index.scss' import { useState } from "react"; import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { login } from '../../store/modules/setToken';   function LoginPage() {     const navigate = useNavigate()     const dispatch = useDispatch()     const [formParams, setFormParams] = useState({         username: 'kanno',         password: '123456',         remember: ''     })     const onFinish = async (values) => { // 提交按钮         await dispatch(login(values)) // 点击提交时调用状态管理中的异步请求方法获取token         navigate('/home') // 跳转到home页面     };     const onFinishFailed = (errorInfo) => {         console.log('Failed:', errorInfo);     };      return (         <div className="login">             <Card style={{ width: 500 }}>                 <div className="title">登录</div>                 <Form                     name="formParams"                     style={{                         width: '100%',                     }}                     initialValues={{                         remember: true,                     }}                     onFinish={onFinish}                     onFinishFailed={onFinishFailed}                     autoComplete="off"                 >                     <Form.Item                         label="名称:"                         name="username"                         rules={[                             {                                 required: true,                                 message: '请输入名称!',                             },                         ]}                     >                         <Input value={formParams.username} />                     </Form.Item>                      <Form.Item                         label="密码:"                         name="password"                         rules={[                             {                                 required: true,                                 message: '请输入密码!',                             }                         ]}                     >                         <Input.Password value={formParams.password} />                     </Form.Item>                      <Form.Item                         name="remember"                         valuePropName="checked"                     >                         <Checkbox>记住密码</Checkbox>                     </Form.Item>                      <div className="bottom">                         <Button type="primary" htmlType="submit">                             提交                         </Button>                     </div>                 </Form>             </Card>         </div>     ); }  export default LoginPage;

6.说明

到这步就已经实现了将请求到的token存储在状态管理中,但是一旦刷新页面,存储在状态管理中的token就会丢失,因此,需要做token的持久化。

token持久化原理比较简单,就是在定义token状态变量的时候就将存储在本地存储的token赋值就行了。所以,在请求到token的时候就将token存储在状态管理和本地存储中,这样就算刷新存储在本地的token也不会丢失,就会在重新初始化的时候赋值到状态变量token中,从而达到token持久化的效果。

7.token持久化处理

在异步请求中存储到本地并且存储到状态管理中

src/store/modules/setToken.js 最终修改后的代码

import { createSlice } from "@reduxjs/toolkit"; import axios from 'axios'  const tokenStore = createSlice({     name: 'setToken',     initialState: {         token: localStorage.getItem('setToken')||'' // 从本地拿取token     },     reducers: {         setToken(state, actions) {             state.token = actions.payload;             console.log("state.token",state.token);         }     } })  const { setToken } = tokenStore.actions; const tokenStoreReducer = tokenStore.reducer;  // 异步请求 function login(data){     return (dispatch)=>{         axios.get('http://localhost:8888/token').then(res=>{             dispatch(setToken(res.data))             localStorage.setItem('setToken',res.data); // 存储在本地         })     } }  export { setToken,login } export default tokenStoreReducer

8.最终效果

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!