如何在 Redux 异步 thunk 中使用 AppDispatch 类型?
Posted
技术标签:
【中文标题】如何在 Redux 异步 thunk 中使用 AppDispatch 类型?【英文标题】:How to use AppDispatch type in in Redux async thunk? 【发布时间】:2021-06-20 08:14:53 【问题描述】:在我的 Redux 异步 thunk 中,我想使用如下所述推断的 AppDispatch 类型:https://redux.js.org/recipes/usage-with-typescript
我按照这里的说明进行操作:https://redux.js.org/recipes/usage-with-typescript#typing-createasyncthunk
但是当在我的自定义 ThunkApiConfig 类型(以下示例中为MyThunkApiConfig
)中使用此 AppDispatch 类型时,将出现循环引用,如下所示:https://codesandbox.io/s/focused-joliot-ho45h?file=/src/usersSlice.ts:
'dispatch' is referenced directly or indirectly in its own type annotation.
这是有道理的,因为调度类型和使用的 thunk 之间存在循环依赖关系。但是如何在异步 thunk 中使用 AppDispatch?
提前感谢您的回答!
【问题讨论】:
这绝对是一个不寻常的设置。使createAsyncSlice
将异步重击作为参数而不是直接使用变量的目标是什么?我可以肯定地找出类型,但我不明白这一点。
类型是dispatch
是DispatchForMiddlewares<M> & Dispatch<A>
其中M
是中间件,A
是操作类型。我需要查找 thunk 中间件的类型。
【参考方案1】:
在MyThunkApiConfig
类型中使用AppDispatch
没有问题。当您这样做 并且 将切片定义为异步操作的函数时,问题就出现了。这会导致切片类型和不应该存在的调度类型之间的紧密耦合。
如果reducer是usersSlice.reducer
那么没有问题。此版本使用 updateUser
aynsc thunk,而后者又使用类型化调度。但是切片的类型不依赖于调度类型。它只关心状态的类型和它创建的动作(在这种情况下,没有)。
另一方面,您的createAsyncSlice
在其参数类型中使用MyThunkApiConfig
。所以这创建了一个循环,其中存储类型取决于切片类型,切片类型取决于存储类型。
通过将updateUser
aysnc thunk 传递给函数而不是直接使用它,我基本上无法得到您想要实现的目标。显然,这里的简单解决方案是“不要那样做”。
如果您想直接为AppDispatch
分配类型,您当然可以这样做。不推荐,因为类型比较复杂,依赖很多泛型类型参数。
export type RootState = users: UsersState
export type AppDispatch = Dispatch<AnyAction> & ThunkDispatch<RootState, null, AnyAction>
在您的示例中,您实际上根本不需要MyThunkApiConfig
。你可以从updateUser
中删除泛型。它们最终会被推断为<User, void, >
,这就足够了。您可以将 slice 参数键入为 asyncThunk: AsyncThunk<User, void, >
,这也可以修复循环类型。
【讨论】:
感谢您的回答! - 抱歉,我忘了说明通用 createAsyncSlice 函数的用途。它用于提取存储异步 thunk 状态的通用功能,很像 diode.suzaku.io/advanced/Pot.html。 - 不幸的是,如果我不使用 MyThunkApiConfig 而是使用asyncThunk: AsyncThunk<User, void, >
,action.payload
将是 unknown
类型。 - 所以如果我理解正确,你建议在这种情况下手动指定RootState
和AppDispatch
,对吗?以上是关于如何在 Redux 异步 thunk 中使用 AppDispatch 类型?的主要内容,如果未能解决你的问题,请参考以下文章