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中显示的购物车商品是客户端浏览器中添加的状态,二者完全独立:
- 服务端每次处理请求时会创建全新的store实例,初始状态就是
cart.data = [],且服务端不会处理客户端触发的购物车添加操作。 - 客户端的store在浏览器初始化后创建,添加商品的操作仅修改客户端store状态,不会同步回服务端。
因此日志里的空数组是服务端store的初始状态,和客户端实际的购物车状态并不冲突。
额外验证点
如果你的购物车数据通过localStorage等方式持久化,客户端初始化时会从本地存储恢复状态,但服务端日志依然会显示空数组,这也符合当前现象。
日志优化(可选)
若不想看到服务端的空购物车日志,可选择:
- 将
wrapper的debug选项设为false,关闭全局debug日志。 - 自定义日志逻辑,仅在客户端打印购物车状态,避免混淆。
内容的提问来源于stack exchange,提问作者Faizan Tariq
相关产品推荐
相关产品推荐

