使用多个中间件时在 redux 存储上正确键入 dispatch
Posted
技术标签:
【中文标题】使用多个中间件时在 redux 存储上正确键入 dispatch【英文标题】:Typing dispatch on a redux store correctly when using multiple middleware 【发布时间】:2021-12-20 17:33:39 【问题描述】:我正在尝试在使用 thunk 中间件和可选中间件记录器 (redux-logger
) 的 redux 存储上配置调度类型。
这可以正确推断商店的 dispatch
上的 thunk 类型...
import createStore, applyMiddleware from 'redux';
import thunk, ThunkMiddleware from 'redux-thunk';
// ...
const preloadedState = undefined;
export const store = createStore(rootReducer, preloadedState, applyMiddleware(thunk as ThunkMiddleware));
当我扩展中间件以包含条件记录器并将一组中间件传播到 applyMiddleware
时,无法正确推断出商店的 dispatch
。
import createStore, applyMiddleware, Middleware from 'redux';
import thunk, ThunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
// ...
const middleware: Middleware[] = [thunk as ThunkMiddleware];
if (Settings.environment === 'development')
const logger = createLogger( collapsed: (_getState, _action, logEntry) => !logEntry.error );
middleware.push(logger);
const preloadedState = undefined;
export const store = createStore(rootReducer, preloadedState, applyMiddleware(...middleware));
这让我发疯了,有什么想法在传播中间件数组时如何解决打字问题?
【问题讨论】:
【参考方案1】:这就是 redux-toolkit 真正派上用场的地方。
他们的docs 提到要这样做
import configureStore from '@reduxjs/toolkit'
import useDispatch from 'react-redux'
import rootReducer from './rootReducer'
const store = configureStore(
reducer: rootReducer,
)
export type AppDispatch = typeof store.dispatch
export const useAppDispatch = () => useDispatch<AppDispatch>() // Export a hook that can be reused to resolve types
export default store
【讨论】:
补充:是的,这将考虑到正确键入的中间件。 啊,好吧,我绝对可以看到使用toolkit
与 thunk 集成的好处,并且默认情况下调度类型正确。除此之外,我可以通过return getDefaultMiddleware().concat(logger)
在middleware
回调中添加redux-logger
,但dispatch
类型仍然被清除。关键是为redux-logger
添加类型...yarn add @types/redux-logger
!【参考方案2】:
您正在执行const middleware: Middleware[] = ...
,它显式地消除了存储在数组中的特定类型,并且只保留它们是Middleware
,而是执行const middleware = [...] as const
以尽可能多地保留有关内容的信息。 (然后使用类型断言允许在不保留这些类型的情况下修改列表,因为无论如何您都不能依赖)
【讨论】:
啊,有趣,你能扩展一下“然后使用类型断言来允许修改列表而不保留这些类型,因为你无论如何都不能依赖”? 当您执行as const
时,它会将其标记为只读数组,因此未定义像 push
这样的方法,因此在记录器中覆盖它以获取记录器会给出稍微不正确的类型被添加。更正确的解决方案是使用const middleware: (ThunkMiddleware | LoggerMiddleware)[]
,这样它就有足够的信息来正确推断调度,并允许您推送记录器,但总的来说这很痛苦。
我发布了答案,然后意识到您为什么要在该列表中开始,并意识到书面答案行不通,所以匆忙修改以上是关于使用多个中间件时在 redux 存储上正确键入 dispatch的主要内容,如果未能解决你的问题,请参考以下文章
使用 redux 构建 React 应用程序时在哪里存储 WebRTC 流
如何在 Typescript 中使用 redux-thunk 使用 ThunkAction 正确键入 thunk?
如何在 react-redux 中正确键入映射到道具的动作创建者