从createStore迁移到configureStore后Redux选择器失效问题
问题
将Redux从createStore转换为configureStore后,原有的选择器无法正常工作,报错如下:
Property 'test' does not exist on type 'ReducerWithInitialState<TestState>'.ts(2339)
相关代码:
Store配置代码
import { Dispatch } from 'react'; import { Action, configureStore } from '@reduxjs/toolkit'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import logger from 'redux-logger'; import { testReducer, } from './reducers'; const rootReducer = () => ({ testReducer }); export const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', middleware: getDefaultMiddleware => getDefaultMiddleware().concat(logger), }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; export const useAppDispatch = (): Dispatch<Action<any>> => useDispatch<AppDispatch>(); export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
选择器代码
export const getTest = (state: RootState) => state.testReducer.test;
尝试在选择器中给testReducer添加getInitialState()能消除错误,但显然这不是正确的解决方式。
解决方案
错误原因
你定义的rootReducer是一个返回对象的函数,而configureStore的reducer参数如果传入函数,会被当作根reducer函数处理,导致RootState里的testReducer类型变成了reducer函数本身(ReducerWithInitialState<TestState>),而不是该reducer管理的状态对象,所以访问.test会报错。
修复步骤
直接将reducer参数设置为包含各个子reducer的对象即可,configureStore会自动调用combineReducers合并它们:
修改后的Store配置代码:
import { Dispatch } from 'react'; import { Action, configureStore } from '@reduxjs/toolkit'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import logger from 'redux-logger'; import { testReducer, } from './reducers'; // 直接定义为对象,不需要包裹成函数 const rootReducer = { testReducer }; export const store = configureStore({ reducer: rootReducer, devTools: process.env.NODE_ENV !== 'production', middleware: getDefaultMiddleware => getDefaultMiddleware().concat(logger), }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; export const useAppDispatch = (): Dispatch<Action<any>> => useDispatch<AppDispatch>(); export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
为什么临时方法不对
调用testReducer.getInitialState()只是获取了该reducer的初始状态值,但这和实际运行时store中的状态类型并不完全匹配(比如状态可能已经被更新过),而且会让类型推导变得混乱,正确的做法是让RootState正确反映store中实际的状态结构。
内容的提问来源于stack exchange,提问作者sewb
相关产品推荐
相关产品推荐

