无法在组件外部直接访问Redux Store,调用getState报错
问题:组件外部普通函数调用Redux Store的getState()报错
错误提示:
Property 'getState' does not exist on type '(initialState: any) => any'
相关代码:
store.ts
import storeHolder from '@lib/storeHolder'; import rootReducer from './rootReducer'; import rootSaga from './rootSaga'; import { createStore, applyMiddleware, compose } from 'redux'; import createSagaMiddleware from 'redux-saga'; const bindMiddleware = (middleware: any) => applyMiddleware(...middleware); const composeEnhancers = (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose; function configureStore(initialState: any) { const sagaMiddleware = createSagaMiddleware(); const store = createStore(rootReducer, initialState, composeEnhancers(bindMiddleware([sagaMiddleware]))) as any; store.sagaTask = sagaMiddleware.run(rootSaga); storeHolder.setStore(store); return store; } export default configureStore;
file-where-i-need.ts
import store from '@redux/store'; import moment from 'moment'; export function formatDateFromnow(date: Date) { const state = store.getState(); <-- 报错行 const { locale } = state.theme.locale; return moment(date).locale(locale).fromNow(); }
问题原因
你导出的configureStore是创建Store的工厂函数,不是已经实例化完成的Store对象。所以你在file-where-i-need.ts里导入的store其实是这个函数,自然没有getState方法。
解决办法
方法1:利用已有的storeHolder获取实例
你已经在configureStore里把实例化后的Store存入了storeHolder,直接从storeHolder取出即可:
// file-where-i-need.ts import storeHolder from '@lib/storeHolder'; import moment from 'moment'; export function formatDateFromnow(date: Date) { // 从storeHolder获取已初始化的Store实例 const store = storeHolder.getStore(); const state = store.getState(); const { locale } = state.theme.locale; return moment(date).locale(locale).fromNow(); }
确保storeHolder实现了getStore方法(如果还没写,补充如下):
// @lib/storeHolder.ts let storeInstance: any; export default { setStore: (store: any) => { storeInstance = store; }, getStore: () => storeInstance };
方法2:直接导出实例化后的Store(适合单Store场景)
修改store.ts,直接创建Store实例并导出,而非导出工厂函数:
// store.ts import storeHolder from '@lib/storeHolder'; import rootReducer from './rootReducer'; import rootSaga from './rootSaga'; import { createStore, applyMiddleware, compose } from 'redux'; import createSagaMiddleware from 'redux-saga'; const bindMiddleware = (middleware: any) => applyMiddleware(...middleware); const composeEnhancers = (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose; const sagaMiddleware = createSagaMiddleware(); // 直接创建Store实例 const store = createStore(rootReducer, composeEnhancers(bindMiddleware([sagaMiddleware]))) as any; store.sagaTask = sagaMiddleware.run(rootSaga); storeHolder.setStore(store); // 导出实例而非函数 export default store;
这样你在file-where-i-need.ts里导入的就是现成的Store实例,可直接调用getState。
注意事项
- 如果是服务端渲染(SSR)场景,推荐用方法1,因为每个请求需要独立的Store实例;
- 纯客户端应用可以用方法2,实现更简单。
内容的提问来源于stack exchange,提问作者niskah-media
相关产品推荐
相关产品推荐

