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

如何让Redux DevTools在Redux Toolkit+Next.js(TypeScript)环境正常工作?

问题分析与解决方案

问题根源

核心问题是每次_app.tsx渲染时都会重新创建Redux Store实例。Redux DevTools默认只会和第一个创建的Store建立连接,后续新生成的Store发出的动作自然不会被追踪——哪怕应用功能本身正常。

在Next.js中,_app.tsx作为全局入口组件,客户端每次路由切换或组件更新都可能触发重新渲染,导致getStore被反复调用,生成多个独立的Store实例。

修复步骤

1. 修改Store文件,实现客户端单例模式

让客户端环境下只创建一次Store,服务端则保持每次请求生成新Store(符合Next.js服务端渲染的无状态要求)。

修改后的store.ts代码:

import { configureStore, ThunkAction, Action, combineReducers } from "@reduxjs/toolkit";
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import UISlice from '@todoSlice/todoSlice'

const rootReducer = combineReducers({
  todo: UISlice,
});

// 客户端环境下缓存Store实例,避免重复创建
let clientStore: ReturnType<typeof configureStore> | undefined;

export default function getStore(incomingPreloadState?: AppState) {
  // 服务端环境每次都创建新Store;客户端仅在首次调用或无缓存实例时创建
  if (typeof window === 'undefined' || !clientStore) {
    clientStore = configureStore({
      reducer: rootReducer,
      preloadedState: incomingPreloadState,
      // Redux Toolkit默认在开发环境开启DevTools,生产环境自动关闭,无需额外配置
    });
  } else if (incomingPreloadState) {
    // 可选:路由切换需更新初始状态时,可在对应Slice中添加重置动作
    // 示例:dispatch(resetTodoState(incomingPreloadState.todo))
  }

  return clientStore;
}

export type AppState = ReturnType<typeof rootReducer>;
export type AppDispatch = ReturnType<typeof getStore>["dispatch"];
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  AppState,
  unknown,
  Action<string>
>; 
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector;

2. 移除错误的DevTools配置

你之前手动引入redux-devtools-extension的composeWithDevTools并关闭configureStore的内置DevTools,这会导致配置冲突。Redux Toolkit已经内置了DevTools集成,默认在开发环境启用,完全无需额外配置外部包。

3. 保持_app.tsx原有逻辑不变

_app.tsx的代码无需修改,因为我们已经在getStore函数中处理了单例逻辑。

验证效果

  • 客户端点击Add!按钮触发的addTodos动作会被DevTools正常记录,状态更新可见
  • 服务端getServerSideProps中执行的intidialTodos动作不会出现在DevTools中,符合预期

额外说明

如果需要在路由切换时更新客户端Store的初始状态,建议在对应的Slice中添加一个重置动作(比如reset),通过dispatch来更新状态,而不是重新创建Store实例,避免DevTools连接中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:15:44