Redux中用增强器替换的getState为何在Action/Saga中不生效?
问题:Redux增强器替换getState后,Action和Saga中仍使用原生getState是否正常?
我通过以下增强器替换Redux的getState方法:
interface ArtificialStateEnhancerProps { getArtificialStateGetter: StateGetterFn; } export const getArtificialStateEnhancer = ({ getArtificialStateGetter }: ArtificialStateEnhancerProps) => { return (createStore: typeof createStoreOriginal) => { return (rootReducer, preloadedState, enhancers) => { const store = createStore(rootReducer, preloadedState, enhancers); const { getState } = store; if (getArtificialStateGetter) { return { ...store, getState: getArtificialStateGetter(getState) }; } return { ...store }; }; }; };
直接调用store.getState()时,自定义的getState能正常工作,但在异步Action或者使用select()的Saga里,调用的却是Redux原生的getState。比如下面这个Action:
export function myAction( slug: string ): ReduxAction<any> { return async ( dispatch: Dispatch, getState: () => any // 这里使用的是Redux原生的getState ): Promise<any> => { const state = getState(); const foo = ...do something with `state` }; }
请问这是预期行为吗?
回答
这不是预期行为,但这是你当前实现方式导致的必然结果。
原因很直接:你只是在创建store时返回了一个新对象,把新对象上的getState替换成了自定义版本,但Redux内部的中间件(比如处理异步Action的thunk中间件)在初始化时,已经捕获了原始store实例的原生getState引用。后续调用异步Action、Saga的select方法时,传递的都是这个提前捕获的原生引用,不会用到你后来替换的版本。
要解决这个问题,你需要修改增强器的实现逻辑,直接修改原始store实例的getState属性,而不是返回一个新的store对象:
export const getArtificialStateEnhancer = ({ getArtificialStateGetter }: ArtificialStateEnhancerProps) => { return (createStore: typeof createStoreOriginal) => { return (rootReducer, preloadedState, enhancers) => { const store = createStore(rootReducer, preloadedState, enhancers); if (getArtificialStateGetter) { // 直接修改原始store的getState方法,确保所有引用都指向自定义版本 store.getState = getArtificialStateGetter(store.getState); } return store; }; }; };
这样修改后,所有依赖store实例getState的场景(包括异步Action、Saga的select),都会使用你自定义的getState方法。
内容的提问来源于stack exchange,提问作者Matthias Max
相关产品推荐
相关产品推荐

