认识Redux Toolkit
Redux Toolkit 是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。
在前面我们学习Redux的时候发现,Redux的编写逻辑还是有点复杂和繁琐的,分别在不同的文件中定义actioncreators和reducer,配置store的增强等;Redux Toolkit可以简化最常见场景下的 Redux 开发,包括配置 store、定义 reducer等。
在很多地方为了称呼方便,我们也将它称为 "RTK";
Redux Toolkit最初是为了帮助解决有关Redux的三个常见问题而创建的:
- 配置Redux store过于复杂
- 必须添加很多软件包才能开始使用Redux
- Redux有太多样板代码
安装redux toolkit:
npm install @reduxjs/toolkit react-redux
redux toolkit的核心api主要是下面几个:
- configureStore():封装了createStore,简化配置,提供一些现成的默认配置项。它可以自动组合slice的reducer,可以添加任何Redux中间件,默认情况下包含redux-thunk,并开启了Redux DevTools扩展。
- createSlice():接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有相应的actions。
- createAsyncThunk():接受一个动作类型字符串和一个返回值为 promise 的函数, 并生成一个 thunk 函数,这个 thunk 函数可以基于之前那个 promise ,dispatch 一组 type 为
pending/fulfilled/rejected的 action
重构代码
我们对counter的reducer进行重构:通过createSlice创建一个slice切片。
// ./store/features/counter.js
import { createSlice } from "@reduxjs/toolkit";
// 创建切片
const counterSlice = createSlice({
name: "counter", // 标记slice的名称
initialState:{ // 初始化值
counter: 888,
},
reducers: { // 相当于之前的reducer函数
addNumberAction(state,{payload}){
state.counter += payload;
},
subNumberAction(state,{payload}){
state.counter -= payload;
}
}
});
// 导出actions和reducer
export const { addNumberAction,subNumberAction } = counterSlice.actions
export default counterSlice.reducer;
createSlice主要包含下面几个参数:
-
name:用户标记slice的名称
-
initialstate: 第一次初始化的值
-
reducers:相当于之前的reducer函数
-
对象类型,并且可以添加很多函数
-
函数类似于原来reducer中的一个case语句;
-
函数的参数:
- state
- action
-
-
createSlice返回值是一个对象,包含多有的actions;
store的创建
configureStore用于创建store对象,常见参数有:
- reducer:将slice中的reducer组成一个对象传入此处;
- middleware:可以使用参数,传入其他的中间件;
- devTools:是否配置devTools工具,默认为true;
import { configureStore } from "@reduxjs/toolkit";
import homeReducer from "./features/home";
import counterReducer from "./features/counter";
const store = configureStore({
reducer: {
home: homeReducer,
counter: counterReducer
}
});
export default store;
异步操作
之前的开发中,我们通过redux-thunk中间件让dispatch中可以进行异步操作。
Redux Toolkit提供的createAsyncThunk也支持我们进行异步操作。
export const getAsyncDataAction = createAsyncThunk("fetch/data",async ()=>{
const res = await axios.get("XXXXX");
return res.data;
})
当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:
- pending:action被发出,但是没有最终结果;
- fulfilled:有返回值的结果;
- rejected:执行过程中有错误或者抛出了异常
我们可以在reducers的entraReducers中监听这些结果:
extraReducers: {
[fetchHomeMultidataAction.pending](state,action){
console.log("pending");
},
[fetchHomeMultidataAction.fulfilled](state,action){
console.log("fulfilled");
console.log(action.payload);
},
[fetchHomeMultidataAction.rejected](state,action){
console.log("rejected");
}
}
打开浏览器的控制台,发现有这个警告。让我们用builder的回调函数代替这个写法。
extraReducers的另外一种写法
extraReducers: (builder)=>{
// 向builder中添加case来监听结果
builder.addCase(fetchHomeMultidataAction.pending,(state,action)=>{
console.log("pending~");
}).addCase(fetchHomeMultidataAction.fulfilled,(state,{ payload })=>{
console.log(payload);
}).addCase(fetchHomeMultidataAction.rejected,()=>{
console.log("获取数据失败了");
})
}
React中的state如何管理
自此Redux中的内容我们了解的差不多了,回顾一下。
目前React中有三种状态的管理方式:
- 组件中自己的state
- contxt数据的共享状态
- Redux管理的状态
在开发中我们该如何选择呢?
没有标准答案。
建议:
- UI相关的组件内部可以维护的状态,在组件内部自己来维护。
- 大部分需要共享的状态,交给Redux来管理和维护;
- 从服务器请求的数据,交给Redux来维护
以上全部,谢谢!