阅读量: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