一、概念
createAsyncThunk 是一个由 Redux Toolkit 提供的函数,用于创建处理异步操作的 thunk action creator。使用 createAsyncThunk 可以简化 Redux 中处理异步操作的流程,使代码更加清晰、简洁。
二、参数说明
import { createAsyncThunk } from "@reduxjs/toolkit";
const myAsyncThunk = createAsyncThunk(
/**
* 一个字符串类型的 action 名称,用于在 Redux 中识别该 action。
* 该名称通常包含操作名称和状态
* */
"myAsyncOperationStatus",
/**
* 异步操作函数,该函数接收两个参数
* 第一个参数是 thunk 的 payload,也就是调用的时候传过来的
* 第二个参数是thunk对象
* dispatch
* 用于 dispatch 其他 action 的函数
* getState
* 用于获取当前 Redux store 中的 state 的函数
* extra
* 性是用于传递额外参数的对象
*
*/
async (arg, { dispatch, getState, extra }) => {
// 异步操作函数,必须返回一个 Promise
const response = await fetch("https://example.com/api/someEndpoint");
return response.json();
},
{} // 可选的配置项
);
三、例子
点击按钮age延迟1秒后+1,在延迟的时候,显示loading。偶数的时候显示报错,并显示提示信息
1、在action目录的user.js文件添加一下代码
import { createAction, createAsyncThunk } from "@reduxjs/toolkit";
const dely = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
});
};
export const ageAddAsync = createAsyncThunk(
"user/ageAddAsync",
async (arg, { dispatch, getState, extra }) => {
const { user } = getState();
console.log(user.age);
await dely();
// 偶数的时候抛错
if (user.age % 2 === 0) {
throw new Error("偶数的时候抛错")
}
}
);
2、修改slice目录里的user.js模块
import { createSlice } from "@reduxjs/toolkit";
import { ageAddAsync } from "./../actions/user";
const userSlice = createSlice({
// 切片名 必须全局唯一
name: "user",
// 初始化状态
initialState: {
age: 1,
name: "李四",
status: "",
error: "",
},
reducers: {
/**
*
* @param {*} state 当前的state
* @param {*} action 穿过来的参数
*/
addAge(state, action) {
return {
...state,
age: state.age + 1,
};
},
},
extraReducers: (builder) => {
builder
.addCase("user/updateName", (state, action) => {
state.name = action.payload.name;
})
// 异步方法的pedding状态
.addCase(ageAddAsync.pending, (state) => {
state.status = "loading";
})
// 异步方法的成功的状态
.addCase(ageAddAsync.fulfilled, (state, action) => {
state.age += 1;
state.status = "successed";
state.error = ''
})
/**
* state
* action 当前的错误信息
*/
.addCase(ageAddAsync.rejected, (state, action) => {
console.log(action)
state.status = "error";
state.age += 1
state.error = action.error.message;
});
},
});
/**
* 导出slice模块的reducer
*/
export default userSlice.reducer;
/**
* 直接导出actions模块
* 这个actions里面的方法和reducer里的方法名
* 一致,直接对象解构
*/
export const { addAge } = userSlice.actions;
3、挂载到configureStore
import { configureStore, createSlice } from "@reduxjs/toolkit";
import user from './slice/user';
const store = configureStore({
reducer: {
user
},
});
export default store;
4、页面中使用
import { useSelector, useDispatch } from "react-redux";
import { ageAddAsync } from "./store/actions/user";
export default function LearnReduxToolkit4() {
const user = useSelector((state) => state.user);
const dispatch = useDispatch();
return (
<div>
<div>
{user.name}--{user.age}
</div>
<div>{user.status}</div>
<div>{user.error}</div>
{/* <div>偶数抛出错误</div> */}
<button onClick={() => dispatch(ageAddAsync())}>延迟一秒+1</button>
</div>
);
}
四、小思考
可以不可以封装一下createSlice和createAsyncThunk,让调用变得更简单🤔