英文:
Redux Toolkit Thunk difference
问题
使用createAsyncThunk和async + dispatch两种方式处理Redux Toolkit中的thunk有什么区别?
创建使用createAsyncThunk的thunk函数时,您可以定义一个名为"yourSlice/deleteColumnAndTasks"的动作类型,并使用async函数来执行异步操作。createAsyncThunk会自动处理异步操作的状态管理,包括请求、成功和失败等情况。它提供了一种更加抽象和自动化的方式来处理异步操作,使您的代码更加简洁和可维护。
另一方面,使用async + dispatch方式,您需要手动管理异步操作的状态。您将传递dispatch函数,并在内部使用try-catch块来处理错误情况。这种方式更加手动,您需要自己处理异步操作的各个阶段,并在错误处理方面具有更多的控制权。
总结来说,createAsyncThunk提供了一种更加抽象和自动化的方式来处理异步操作,而async + dispatch方式则更加手动,您需要更多的自定义控制。选择哪种方式取决于您的项目需求和个人偏好。
英文:
I was searching about thunks on Redux-toolkit and I found 2 ways of dealing with them:
createAsyncThunk or just using async + dispatch
Using createAsyncThunk:
export const deleteColumnAndTasks = createAsyncThunk(
'yourSlice/deleteColumnAndTasks',
async ({ boardId, column }) => {
const tasksToDelete = column.taskIds || [];
await changeBoardColumns({
operationType: 'delete',
targetBoardId: boardId,
columnId: column.id
});
await deleteColumn({ columnId: column.id });
await Promise.all(tasksToDelete.map(taskId => deleteTask({ taskId })));
}
);
Using async + dispatch
export const deleteColumnAndTasks = ({ boardId, column }) => async dispatch => {
const tasksToDelete = column.taskIds || [];
try {
await dispatch(changeBoardColumns({
operationType: 'delete',
targetBoardId: boardId,
columnId: column.id
}));
await dispatch(deleteColumn({ columnId: column.id }));
await Promise.all(tasksToDelete.map(taskId => dispatch(deleteTask({ taskId }))));
} catch (error) {
console.log('Error deleting column and tasks', error);
}
};
What is the difference between the two ways?
答案1
得分: 1
它们都旨在分派操作以更改存储状态。它们都将返回一个 Promise 对象,正如所述。这就是它们的相似之处。
createAsyncThunk()
是一个工厂,用于注册并返回一个函数(操作创建器),该函数将在将来被调用,并且设计用于返回一个 Promise 对象。文档中说明:
它基于传递的操作类型前缀生成 Promise 生命周期操作类型,并返回一个 thunk 操作创建器,该操作创建器将运行 Promise 回调并基于返回的 Promise 分派生命周期操作。
此外,文档中提到的生命周期操作:
createAsyncThunk
将使用createAction
生成三个 Redux 操作创建器:pending
、fulfilled
和rejected
。每个生命周期操作创建器都将附加到返回的 thunk 操作创建器上,以便您的减速器逻辑可以引用操作类型并在分派时响应操作。每个操作对象将在action.meta
下包含当前的唯一 requestId 和 arg 值。
因此,如果重要的设计选择是跟踪/监视/订阅您正在分派的异步操作,createAsyncThunk()
为您提供了无需额外努力即可完成所有这些操作的方法。
例如,在 createSlice()
调用中,可以执行以下操作:
extraReducers: builder => {
builder
.addCase(deleteColumnAndTasks.pending, (state, action) => {
// 执行 pending 操作
})
.addCase(deleteColumnAndTasks.fulfilled, (state, action) => {
state.value = [action.payload, ...state.value];
})
// 等等。
})
第二个示例只是一个在调用时同步执行的函数,它使用柯里化来传递 boardId
、column
和 dispatch
函数的引用。createAsyncThunk()
自动提供的所有工具都不存在。如果需要这些功能,将需要单独编写它们。
英文:
They both are designed to dispatch actions to change the state of the store. They both will return a Promise object as written. That is where the similarities end.
createAsyncThunk()
is a factory that registers and returns a function (action creator) that will be called in the future and that is designed to return a Promise object. The docs state:
> It generates promise lifecycle action types based on the action type
> prefix that you pass in, and returns a thunk action creator that will
> run the promise callback and dispatch the lifecycle actions based on
> the returned promise.
Also Life Cycle Actions from the docs
> createAsyncThunk
will generate three Redux action creators using
> createAction
: pending
, fulfilled
, and rejected
. Each lifecycle action
> creator will be attached to the returned thunk action creator so that
> your reducer logic can reference the action types and respond to the
> actions when dispatched. Each action object will contain the current
> unique requestId and arg values under action.meta
.
So if it is an important design choice to keep track/monitor/subscribe to the async actions you are dispatching, createAsyncThunk()
provides you the means to do all of that with no extra effort on your own.
For example, in a createSlice()
call one can do something like this:
<!-- language: lang-js -->
extraReducers: builder =>
builder
.addCase(deleteColumnAndTasks.pending, (state, action) => {
// do pending action
})
.addCase(deleteColumnAndTasks.fulfilled, (state, action) => {
state.value = [action.payload, ...state.value];
})
// etc.
)
<!-- end snippet -->
One other important capability that createAsyncThunk()
provides is the ability to easily cancel the async action based upon a user defined condition
.
=====
The second example is simply a synchronously executed (at call time) function that uses currying to pass in boardId
, column
and a reference the to dispatch
function. All of the tooling provided automagically by createAsyncThunk()
does not exist. Those features, if required will need to be written separately.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论