Redux ToolKit:是不是可以在由 createAsyncThunk 创建的一个操作中调度来自同一切片的其他操作
Posted
技术标签:
【中文标题】Redux ToolKit:是不是可以在由 createAsyncThunk 创建的一个操作中调度来自同一切片的其他操作【英文标题】:Redux ToolKit: is it possible to dispatch other actions from the same slice in one action created by createAsyncThunkRedux ToolKit:是否可以在由 createAsyncThunk 创建的一个操作中调度来自同一切片的其他操作 【发布时间】:2020-12-10 11:27:39 【问题描述】:我正在使用redux-toolkit
和createAsyncThunk
来处理异步请求。
我有两种异步操作:
从 API 服务器获取数据
更新 API 服务器上的数据
export const updateData = createAsyncThunk('data/update', async (params) =>
return await sdkClient.update( params )
)
export const getData = createAsyncThunk('data/request', async () =>
const data = await sdkClient.request()
return data
)
然后我将它们添加到extraReducers
中
const slice = createSlice(
name: 'data',
initialState,
reducers: ,
extraReducers: (builder: any) =>
builder.addCase(getData.pending, (state) =>
//...
)
builder.addCase(getData.rejected, (state) =>
//...
)
builder.addCase(
getData.fulfilled,
(state, payload : PayloadAction< data: any >) =>
state.data = payload.data
)
builder.addCase(updateData.pending, (state) =>
//...
)
builder.addCase(updateData.rejected, (state) =>
//...
)
builder.addCase(updateData.fulfilled, (state) =>
//<--- here I want to dispatch `getData` action to pull the updated data
)
,
)
在我的组件中,我有一个触发更新操作调度的按钮。但是我点击按钮后发现,尽管服务器上的数据正在更新,但页面上的数据并没有同时更新。
function MyComponent()
const dispatch = useDispatch()
const data = useSelector((state) => state.data)
useEffect(() =>
dispatch(getData())
, [dispatch])
const handleUpdate = () =>
dispatch(updateData())
return (
<div>
<ul>
// data goes in here
</ul>
<button onClick=handleUpdate>update</button>
</div>
)
我在更新数据后尝试在handleUpdate
中添加dispatch(getData())
。但是由于异步重击,它不起作用。我想知道我是否可以在updateData
的生命周期操作中调度getData
操作,即
builder.addCase(updateData.fulfilled, (state) =>
dispatch(getData())//<--- here I want to dispatch `getData` action to pull the updated data
)
【问题讨论】:
【参考方案1】:可能它不是实际的并且问题已经过时了,但是createAsyncThunk
的有效载荷创建者中有thunkAPI
作为第二个参数,所以它可以像这样使用
export const updateData = createAsyncThunk('data/update', async (params, dispatch) =>
const result = await sdkClient.update( params )
dispatch(getData())
return result
)
【讨论】:
【参考方案2】:首先:请注意,reducer 总是需要是没有副作用的纯函数。所以你永远不能在那里dispatch
任何东西,因为那会是一个副作用。即使你设法做到了,redux
也会警告你。
现在讨论手头的问题。
您可以创建一个 thunk 来调度并等待您的 updateData
调用完成,然后调度您的 getData
调用:
export const updateAndThenGet = (params) => async (dispatch) =>
await dispatch(updateData(params))
return await dispatch(getData())
//use it like this
dispatch(updateAndThenGet(params))
或者,如果这两个步骤总是一起调度,您可以考虑将它们组合起来:
export const updateDataAndGet = createAsyncThunk('data/update', async (params) =>
await sdkClient.update( params )
const data = await sdkClient.request()
return data
)
【讨论】:
您的意思是“await dispatch(updateDataAndGet (params))”而不是“await dispatch(updateData(params))”希望这是一个错字吗? 这是两个不同的示例解决方案。第一个分别引用了 OP 的updateData
thunk 和 getData
thunk。第二个将它们组合成一个新的名称updateDataAndGet
以上是关于Redux ToolKit:是不是可以在由 createAsyncThunk 创建的一个操作中调度来自同一切片的其他操作的主要内容,如果未能解决你的问题,请参考以下文章
Redux-Toolkit createAsyncThunk with Typescript
Redux工具包 - Redux Toolkit的异步操作(发送网络请求)