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

如何在Next.js v13 App目录中使用服务端Redux?含报错解决与示例

在Next.js 13 App目录中使用Redux的完整方案

1. 能否替代Next.js Redux Wrapper使用Redux?

完全可以。Next.js 13 App Router的组件模型(服务端/客户端组件分离)和Pages Router不同,不需要依赖next-redux-wrapper,直接结合Redux Toolkit与React的Provider就能实现状态管理,同时支持服务端状态初始化。

2. 如何创建服务端状态?

在App Router中,你可以在服务端组件中获取初始数据(比如从API、数据库拉取),将其作为预加载状态传递给Redux store,再通过客户端组件的Provider包裹子组件,让客户端组件访问到初始化后的状态。

3. React createContext错误的解决方法

这个错误几乎都是因为在服务端组件中使用了客户端专属API(比如createContext、Redux的Provider或useSelector/useDispatch hooks)。App Router规定服务端组件不能调用客户端API,解决步骤:

  • 所有涉及Redux Provider、使用Redux hooks的组件,必须在文件顶部添加'use client'指令,标记为客户端组件
  • 服务端组件仅负责获取初始数据,不参与状态管理的逻辑实现

4. 可运行的示例代码

第一步:创建Redux Store(store.ts)

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

interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0,
};

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => { state.value += 1; },
    decrement: (state) => { state.value -= 1; },
  },
});

export const { increment, decrement } = counterSlice.actions;

export const makeStore = (preloadedState?: Partial<CounterState>) => {
  return configureStore({
    reducer: { counter: counterSlice.reducer },
    preloadedState,
  });
};

export type AppStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<AppStore['getState']>;
export type AppDispatch = AppStore['dispatch'];

第二步:创建Redux Provider组件(Providers.tsx)

'use client';

import { useRef } from 'react';
import { Provider } from 'react-redux';
import { makeStore, AppStore } from './store';

export default function Providers({
  children,
  initialState,
}: {
  children: React.ReactNode;
  initialState?: Parameters<typeof makeStore>[0];
}) {
  const storeRef = useRef<AppStore>();
  if (!storeRef.current) {
    storeRef.current = makeStore(initialState);
  }

  return <Provider store={storeRef.current}>{children}</Provider>;
}

第三步:服务端组件注入初始状态(app/page.tsx)

import Providers from './Providers';
import Counter from './Counter';

// 模拟服务端获取初始数据
async function getInitialCounterValue() {
  await new Promise(resolve => setTimeout(resolve, 100));
  return { value: 5 };
}

export default async function Home() {
  const initialState = await getInitialCounterValue();

  return (
    <Providers initialState={{ counter: initialState }}>
      <main>
        <h1>Next.js 13 App Router + Redux</h1>
        <Counter />
      </main>
    </Providers>
  );
}

第四步:使用Redux的客户端组件(Counter.tsx)

'use client';

import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './store';
import type { RootState } from './store';

export default function Counter() {
  const count = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
}

以上代码可直接在在线编辑器中运行,只需安装依赖(@reduxjs/toolkit react-redux next react react-dom)即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:10:35