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

Redux状态日志异常:Next Redux Wrapper与Redux ToolKit联用问题

问题描述

使用Redux ToolKit管理状态,通过Next Redux Wrapper实现服务端渲染(SSR)和查询缓存。业务流程正常运行,UI上能看到购物车已添加商品且状态更新正常,但Next Redux Wrapper的debug日志却显示购物车数据为空数组[]。

相关代码

CartSlice.js

import { createSlice } from '@reduxjs/toolkit';

export const cartSlice = createSlice({
  name: 'cart',
  initialState: { data: [] },
  reducers: {
    addToCart: (state, action) => {
      const itemInCart = state.data.find((item) => item.id === action.payload.id);
      if (itemInCart) {
        itemInCart.quantity += action.payload.quantity;
      } else {
        state.data.push({ ...action.payload });
      }
    }
  },
});

export const cartReducer = cartSlice.reducer;
export const { addToCart } = cartSlice.actions;

ServiceApi.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'

export const serviceApi = createApi({
  reducerPath: 'serviceApi',
  baseQuery: fetchBaseQuery({ baseUrl: '<base-url>' }),
  extractRehydrationInfo(action, { reducerPath }) {
    if (action.type === HYDRATE) {
      return action.payload[reducerPath]
    } 
  },

  endpoints: (builder) => ({
    getItemById: builder.query({ query: (id) => `id/${id}` }),
    getItems: builder.query({ query: () => `/` }),
  }),
})

export const { getRunningQueriesThunk } = serviceApi.util
export const { useGetItemByIdQuery, useGetItemsQuery } = serviceApi
export const { getItemById, getItems } = serviceApi.endpoints;

store.js

import { configureStore } from '@reduxjs/toolkit'
import { serviceApi } from './serviceApi'
import { createWrapper } from "next-redux-wrapper";
import { cartSlice } from "./cartSlice";

export const store = configureStore({
  reducer: {
    [cartSlice.name]: cartSlice.reducer,
    [serviceApi.reducerPath]: serviceApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(serviceApi.middleware),
  })

const makeStore = () => store
export const wrapper = createWrapper(makeStore, {debug: true});

getServerSideProps用法

export const getServerSideProps = wrapper.getServerSideProps(
  (store) => async (context) => {
    const { id } = context.query;
    store.dispatch(serviceApi.endpoints.getItemById.initiate(parseInt(id)));
    await Promise.all(store.dispatch(serviceApi.util.getRunningQueriesThunk()));
    return {
      props: {},
    };
  }
);

wrappedStore用法

const { store, props } = wrapper.useWrappedStore(pageProps);

原因分析与解决方案

核心原因

Next Redux Wrapper的debug日志展示的是服务端渲染阶段的store状态,而UI中显示的购物车商品是客户端浏览器中添加的状态,二者完全独立:

  1. 服务端每次处理请求时会创建全新的store实例,初始状态就是cart.data = [],且服务端不会处理客户端触发的购物车添加操作。
  2. 客户端的store在浏览器初始化后创建,添加商品的操作仅修改客户端store状态,不会同步回服务端。

因此日志里的空数组是服务端store的初始状态,和客户端实际的购物车状态并不冲突。

额外验证点

如果你的购物车数据通过localStorage等方式持久化,客户端初始化时会从本地存储恢复状态,但服务端日志依然会显示空数组,这也符合当前现象。

日志优化(可选)

若不想看到服务端的空购物车日志,可选择:

  • 将wrapper的debug选项设为false,关闭全局debug日志。
  • 自定义日志逻辑,仅在客户端打印购物车状态,避免混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:50:22