Redux Toolkit跨slice调用getState取值报ReferenceError
问题描述
从存储用户信息的其他Redux slice取值时触发ReferenceError报错。已知Redux本身支持跨slice获取状态,但本次报错信息提示slice无法找到store实例。目前已经在应用根层级通过Provider完成store注入,需要确认getState方法是否仅能在组件中使用,不支持slice之间跨片调用。
现有代码结构
根入口文件
import React from 'react'; import ReactDOM from 'react-dom'; import { HashRouter } from 'react-router-dom'; import App from './App'; import './index.css'; // Redux Tool Kit import { store } from './app/store'; import { Provider } from 'react-redux'; ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById('root') );
misc切片文件
import { RootState, store } from './store'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; export interface miscState { dayNumber: true, dayOfWeek: false, }; export const miscSlice = createSlice({ name: 'misc', initialState, reducers: { setDisplayDay: (state, action: PayloadAction < { bool: boolean;type: string } > ) => { const { user, uid } = store.getState().global.currentUser; const setDisplay = async() => { const docRef = doc(db, colDynamic(user)[0], uid); await updateDoc(docRef, { [action.payload.type]: action.payload.bool, }); }; }, }, }); // Values export const MiscCurrentState = (state: RootState) => state.misc; // Action creators are generated for each case reducer function export const { setDisplayDay } = miscSlice.actions; export default miscSlice.reducer;
store配置文件
import { configureStore } from '@reduxjs/toolkit'; // Global import globalReducer from './globalSlice'; // Misc import miscReducer from './miscSlice'; export const store = configureStore({ reducer: { global: globalReducer, misc: miscReducer, }, }); // Infer the `RootState` and `AppDispatch` types from the store itself export type RootState = ReturnType<typeof store.getState>; // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} export type AppDispatch = typeof store.dispatch;
报错截图

问题原因与修复方案
getState并非只能在组件内使用,本次ReferenceError的核心原因是模块循环引用:store配置文件导入了miscSlice的reducer,miscSlice又在文件顶部反向导入store实例,模块加载阶段miscSlice拿到的是未完成初始化的store临时值,调用getState()自然触发报错。- 现有写法本身违反Redux设计规则:reducer必须是纯同步函数,禁止在reducer内部编写异步逻辑、直接导入store实例调用外部API。当前代码里定义的
setDisplay异步函数声明后从未执行,本身也不会生效。 - 代码里还存在其他显性问题:miscSlice未定义
initialState就直接使用、miscState接口的属性值直接写了true/false字面量而非boolean类型,这些问题也会触发编译/运行报错,需要一并修复。 - 正确的跨slice取值+异步逻辑实现方式:使用Redux Toolkit默认集成的thunk处理异步逻辑,thunk回调的入参自带
getState方法,可以直接获取全量store状态,不需要手动导入store实例,从根源上避免循环引用问题。参考写法如下:
// 移除slice文件顶部对store的导入,把原来reducer里的异步逻辑抽成thunk export const setDisplayDay = (payload: {bool: boolean; type: string}) => async (dispatch, getState) => { // 直接通过thunk提供的getState取全量状态,无循环引用问题 const { user, uid } = getState().global.currentUser; const docRef = doc(db, colDynamic(user)[0], uid); await updateDoc(docRef, { [payload.type]: payload.bool, }); // 异步操作完成后,再dispatch纯action同步更新store状态 // dispatch(同步更新状态的action) }
- 如果确实需要在非组件、非thunk的公共逻辑中读取store状态,不要在slice文件顶部导入store,把相关逻辑放到store初始化完成后再执行,避免模块加载阶段拿到未初始化的store实例。
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

