You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13 App Router中Redux Toolkit代码错误排查请求

Next.js 13 App Router 集成 Redux Toolkit 错误排查指南

核心配置错误排查

以下是结合你提到的文件(apiSlice、usersApiSlice、authSlice、Provider、store、layout、登录页),整理的高频错误点及修正方案:

1. Store 配置问题

确保使用 configureStore 正确集成 RTK Query 中间件,避免服务端渲染冲突:

// store.js
import { configureStore } from '@reduxjs/toolkit';
import { apiSlice } from './apiSlice';
import authReducer from './authSlice';

export const store = configureStore({
  reducer: {
    [apiSlice.reducerPath]: apiSlice.reducer,
    auth: authReducer,
  },
  // 必须注入 RTK Query 中间件
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(apiSlice.middleware),
});
  • 禁止在 Server Component 中直接引用 store,RTK 仅支持 Client Component。

2. Redux Provider 配置问题

Provider 必须是客户端组件(添加 'use client' 指令),否则服务端渲染会抛出上下文错误:

// providers.jsx
'use client';

import { Provider } from 'react-redux';
import { store } from './store';

export function ReduxProvider({ children }) {
  return <Provider store={store}>{children}</Provider>;
}

在根 layout 中全局包裹:

// app/layout.jsx
import { ReduxProvider } from './providers';

export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <ReduxProvider>{children}</ReduxProvider>
      </body>
    </html>
  );
}
  • 错误点:若 Provider 未加 'use client',会导致服务端无法识别 Redux 上下文。

3. API Slice 配置问题

确保 baseQuery 指向正确的 Next.js API 路由,扩展端点时语法正确:

// apiSlice.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const apiSlice = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }), // 对应 app/api 下的路由
  tagTypes: ['User'],
  endpoints: () => ({}),
});

扩展用户 API 端点时,需正确调用 injectEndpoints:

// usersApiSlice.js
import { apiSlice } from './apiSlice';

export const usersApiSlice = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    login: builder.mutation({
      query: (credentials) => ({
        url: '/auth/login',
        method: 'POST',
        body: credentials,
      }),
    }),
  }),
});

export const { useLoginMutation } = usersApiSlice;
  • 错误点:baseUrl 配置错误会导致请求 404;injectEndpoints 拼写错误会引发类型错误。

4. Auth Slice 与登录组件问题

Auth Slice 中需避免服务端访问 localStorage,登录组件必须是客户端组件:

// authSlice.js
import { createSlice } from '@reduxjs/toolkit';

// 仅在客户端读取 localStorage
const initialState = {
  userInfo: typeof window !== 'undefined' 
    ? JSON.parse(localStorage.getItem('userInfo')) 
    : null,
};

const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    setCredentials: (state, action) => {
      state.userInfo = action.payload;
      localStorage.setItem('userInfo', JSON.stringify(action.payload));
    },
    logout: (state) => {
      state.userInfo = null;
      localStorage.removeItem('userInfo');
    },
  },
});

export const { setCredentials, logout } = authSlice.actions;
export default authSlice.reducer;

登录页面必须添加 'use client',并正确处理 RTK Query 的 mutation:

// app/login/page.jsx
'use client';

import { useState } from 'react';
import { useLoginMutation } from '../../features/api/usersApiSlice';
import { useDispatch } from 'react-redux';
import { setCredentials } from '../../features/auth/authSlice';

export default function LoginPage() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [login, { isLoading }] = useLoginMutation();
  const dispatch = useDispatch();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      // 使用 unwrap() 获取真实响应或抛出错误
      const userData = await login({ email, password }).unwrap();
      dispatch(setCredentials(userData));
      // 登录成功后跳转
    } catch (err) {
      console.error(err.data?.message || err.error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        required
      />
      <button type="submit" disabled={isLoading}>
        {isLoading ? '登录中...' : '登录'}
      </button>
    </form>
  );
}
  • 错误点:未加 'use client' 会导致无法使用 React Hooks;未用 unwrap() 无法捕获具体请求错误;服务端访问 localStorage 会抛出 window is undefined。

5. 终端错误针对性排查

根据常见终端错误快速定位:

  • Error: Cannot access 'window' on the server:检查 authSlice 或其他代码中是否在服务端访问了客户端 API(如 localStorage),需添加 typeof window !== 'undefined' 判断。
  • TypeError: Cannot read properties of undefined (reading 'injectEndpoints'):确认 usersApiSlice 正确导入了 apiSlice,且 apiSlice 已正确调用 createApi。
  • Error: Could not find "store" in the context of "Connect(LoginPage)":检查 Provider 是否正确包裹了登录页面,或 Provider 未添加 'use client' 指令。

内容的提问来源于stack exchange,提问作者Bipin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:10:25