Next 13 App目录集成Redux报错:初始化前无法访问apiSlice
Next 13 App目录下Redux报错"Cannot access 'apiSlice' before initialization"的解决办法
问题现象
在Next 13 App目录结构中使用Redux时,出现ReferenceError: Cannot access 'apiSlice' before initialization错误,报错指向store.ts中的[apiSlice.reducerPath]: apiSlice.reducer行,推测是循环依赖导致,但无法定位具体位置。
核心原因
大概率是**store.ts和apiSlice所在文件形成了循环引用**:
store.ts需要导入apiSlice来注册reducerapiSlice所在文件又导入了store.ts中的内容(比如AppDispatch类型、useAppDispatch钩子)
这种互相引用会导致模块初始化顺序混乱,出现"未初始化就访问"的错误。
解决步骤
1. 拆分类型定义到独立文件
创建单独的redux/types.ts文件,存放Redux相关类型,避免store和apiSlice互相导入类型:
// redux/types.ts import type { store } from './store'; // 导出RootState和AppDispatch类型 export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch;
2. 调整store.ts的导入和导出
确保store.ts先导入apiSlice,再从独立类型文件导入类型,避免提前导出被apiSlice引用的内容:
// redux/store.ts import { configureStore } from '@reduxjs/toolkit'; import { apiSlice } from './apiSlice'; import { useDispatch, useSelector } from 'react-redux'; // 先创建store,依赖apiSlice export const store = configureStore({ reducer: { [apiSlice.reducerPath]: apiSlice.reducer, }, // 必须添加apiSlice的middleware,RTK Query需要它处理请求 middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiSlice.middleware), }); // 从独立类型文件导入,避免apiSlice直接引用store.ts import type { RootState, AppDispatch } from './types'; export const useAppDispatch = () => useDispatch<AppDispatch>(); export const useAppSelector = <T>(selector: (state: RootState) => T) => useSelector(selector);
3. 修正apiSlice的导入
让apiSlice只从独立类型文件导入必要类型,不再直接引用store.ts:
// redux/apiSlice.ts import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import type { RootState } from './types'; export const apiSlice = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ getAdminUser: builder.query({ query: () => '/admin/user', }), }), }); // 导出RTK Query生成的钩子 export const { useLazyGetAdminUserQuery } = apiSlice;
4. 检查业务钩子的导入
确保admin-user.tsx只从对应文件导入钩子,没有间接导致循环:
// hooks/admin-user.tsx import { useLazyGetAdminUserQuery } from '../redux/apiSlice'; import { useAppDispatch } from '../redux/store'; export function useAdminUser() { const [getAdminUser] = useLazyGetAdminUserQuery(); const dispatch = useAppDispatch(); // 你的业务逻辑 }
关键注意点
- RTK Query不需要
apiSlice直接依赖store,通过Redux Provider就能自动关联,不要在apiSlice里直接导入store实例 - 类型引用是循环依赖的常见诱因,拆分类型到独立文件是最有效的解决方式
- 确保
store.ts中先初始化store,再导出依赖store的类型和钩子
内容的提问来源于stack exchange,提问作者Nightwolf
相关产品推荐
相关产品推荐

