1.安装插件
javascript
npm i @reduxjs/toolkit react-redux
2.新建状态管理文件
在src下新建store文件夹,store文件夹下新建模块文件夹(modules)和入口文件(index.js),modules文件夹下新建setToken.js文件
3.配置setToken.js
javascript
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
javascript
// 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
javascript
// 该文件为主组件
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
javascript
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 最终修改后的代码
javascript
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