redux toolkit 使用指南
前言
redux toolkit 是redux官方出品的工具包,能够便捷的使用redux进行状态管理。
redux toolkit文档:传送门
redux toolkit中文文档:传送门
安装
- yarn 安装:
yarn add react-redux @reduxjs/toolkit
- npm 安装
npm i react-redux @reduxjs/toolkit
使用
1. 创建切片
Slice切片 类似umijs中的model模块,就是将整个数据仓库分割成一个个单独的文件,可以按照功能或页面进行分类,方便管理和维护。
切片”是应用中单个功能的 Redux reducer 逻辑和 action 的集合
使用createSlice
函数创建切片,属性包含name
、initstate
、reducers
和extraReducers
。
-
name
:相当于这个切片的名字,每个切片都要有自己的名字,用于在整个数据仓库中做区分。 -
initstate
: 就是这个仓库切片要存储的信息。redux的所有操作本质上就是操作state。 -
reducers
:存放所有的reducer,reducer可以理解为仓库管理员,对状态数据的操作必须要通过reducer
来进行执行。每一个reducer
函数都对应着一个action
。并且会集成到slice.actions
中。 -
extraReducers
:用来处理异步操作的reducer,redux本身不支持异步操作数据,所以redux toolkit集成了redux-thunk
,通过它可以对数据进行异步操作。流程如下:- 在
createSlice
函数的前面,使用createAsyncThunk
函数创建异步操作函数。 - 使用内部集成的
thunkAPI
可以操作切片的各种action
。 - 将异步函数放入
extraReducers
中,每个异步函数都有三种状态:pending
、fufilled
、rejected
。
- 在
使用流程:
step1:
使用createSlice()
函数创建切片,
step2:
将异步函数和所有reducer
函数导出,格式如上示例。
将切片默认导出。代码如下:
// 文件所在目录:src/pages/counter/slice.js
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
//- 异步方法
export const asyncSetNum = createAsyncThunk(
"counter/asyncSetNum",
(payload, thunkAPI) => {
//此处仅用于测试异步,真实项目中可进行ajax请求等操作
setTimeout(() => {
thunkAPI.dispatch(counterSlice.actions.setNum(payload));
}, 3000);
}
);
export const counterSlice = createSlice({
name: "counter",
initialState: {
count: 0,
},
reducers: {
increate: (state) => {
state.count += 1;
},
decreate: (state) => {
state.count -= 1;
},
setNum: (state, { payload }) => ({ ...state, ...payload }),
},
extraReducers: {
[asyncSetNum.fulfilled]: (state, action) => state,
},
});
//- reducer方法的每个case都会生成一个action
export const { increate, decreate, addNum } = counterSlice.actions;
export default counterSlice.reducer;
2. 创建仓库、引入切片
使用configureStore()
函数创建仓库,属性包含reducer
、middleware
、devTools
、preloadedState
、enhancers
。
step1: 将所有切片引入,配置到仓库的reducer
中。示例代码如下:
// 文件所在目录:src/store/index.js
import { configureStore } from "@reduxjs/toolkit";
import counter from "../pages/counter/model.js";
import common from "./models/common.js";
export const store = configureStore({
reducer: {
counter,
common,
},
});
step2: 配置到项目中。示例代码如下:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { store } from "./store";
import { Provider } from "react-redux";
import { BrowserRouter as Router } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>
</React.StrictMode>
);
3. 使用仓库
step1: 从react-redux
库中引入useSelector()
和useDispatch()
函数。
useSelector()
用于获取仓库中的数据。useDispatch()
用于执行仓库中的action
。
step2: 从切片中引入所需的action
函数。
step3: 通过dispatch
对象使用各种action
函数。
示例代码如下:
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increate, decreate, asyncSetNum } from "./model";
const Counter = () => {
const { count } = useSelector((state) => state.counter);
const dispatch = useDispatch();
return (
<div>
<button
onClick={() => {
dispatch(decreate());
}}
>
-
</button>
{count}
<button
onClick={() => {
dispatch(increate());
}}
>
+
</button>
<button
onClick={() => {
dispatch(asyncSetNum({ count: 10 }));
}}
>
异步设置为10
</button>
</div>
);
};
export default Counter;
总结
上面列举的只是个人比较习惯的一种写法,更多redux toolkit使用技巧可以自行查阅相关文档。