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

如何通过next-redux-wrapper在Next.js页面间共享状态避免重复初始化?

如何避免在Next.js每个页面重复执行Redux初始化Action?

当前我在Next.js项目中使用next-redux-wrapper管理状态,首页和子页面都需要执行相同的两个初始化Action来设置应用初始状态,但目前每个页面都重复写了相同的getInitialProps逻辑,希望能优化避免重复代码。

现有代码示例

首页(pages/index.tsx)

const Home: NextPage = () => { 
  return (<> <Link href='/2'><a>Go to page 2</a></Link> </>)
}

Home.getInitialProps = wrapper.getInitialPageProps(
  ({ dispatch }) =>
    async () => {
      await dispatch(addInitialSources('book'))
      await dispatch(addCategoriesMenu('book'))
    }
);
export default Home

子页面(pages/[id]/index.tsx)

const SecondPage: NextPage = () => { 
  return (<> <Link href='/'><a>Go Home</a></Link> </>)
}

SecondPage.getInitialProps = wrapper.getInitialPageProps(
  ({ dispatch }) =>
    async () => {
      await dispatch(addInitialSources('book'))
      await dispatch(addCategoriesMenu('book'))
    }
);
export default SecondPage

pages/_app.tsx配置

import 'tailwindcss/tailwind.css';
import type { AppProps } from 'next/app'
import { wrapper } from "@store/store" 
function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
export default wrapper.withRedux(MyApp)  

优化方案

方案1:封装复用的初始化函数

将重复的初始化逻辑抽成独立函数,在需要的页面中直接调用,减少代码重复。

  1. 创建复用函数(比如utils/initAppState.ts):
import { addInitialSources, addCategoriesMenu } from '@store/actions';

export const initAppState = async (dispatch: any) => {
  await dispatch(addInitialSources('book'));
  await dispatch(addCategoriesMenu('book'));
};
  1. 在页面中调用该函数:
// 首页
Home.getInitialProps = wrapper.getInitialPageProps(
  ({ dispatch }) => async () => {
    await initAppState(dispatch);
  }
);

// 子页面
SecondPage.getInitialProps = wrapper.getInitialPageProps(
  ({ dispatch }) => async () => {
    await initAppState(dispatch);
  }
);

方案2:在_app.tsx中全局执行初始化

利用_app.tsx作为所有页面的入口,在这里统一执行初始化逻辑,无需每个页面单独配置。

修改pages/_app.tsx:

import 'tailwindcss/tailwind.css';
import type { AppProps } from 'next/app'
import { wrapper } from "@store/store";
import { addInitialSources, addCategoriesMenu } from '@store/actions';

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

MyApp.getInitialProps = wrapper.getInitialAppProps(
  ({ dispatch }) => async ({ Component, ctx }) => {
    // 全局执行初始化Action
    await dispatch(addInitialSources('book'));
    await dispatch(addCategoriesMenu('book'));
    
    // 保留页面自身的getInitialProps逻辑(如果有的话)
    const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
    
    return { pageProps };
  }
);

export default wrapper.withRedux(MyApp);

方案3:检查状态是否已初始化,避免重复执行

在初始化逻辑中先判断状态是否已存在,仅当状态未初始化时才执行Action,这样即使多个页面调用也不会重复触发。

修改复用的初始化函数:

import { addInitialSources, addCategoriesMenu } from '@store/actions';
import { selectSources, selectCategoriesMenu } from '@store/selectors'; // 导入对应的状态选择器

export const initAppState = async (dispatch: any, getState: any) => {
  const state = getState();
  // 根据你的状态结构调整判断条件
  const hasInitializedSources = !!selectSources(state);
  const hasInitializedCategories = !!selectCategoriesMenu(state);

  if (!hasInitializedSources) {
    await dispatch(addInitialSources('book'));
  }
  if (!hasInitializedCategories) {
    await dispatch(addCategoriesMenu('book'));
  }
};

然后在页面中调用时传入getState:

Home.getInitialProps = wrapper.getInitialPageProps(
  ({ dispatch, getState }) => async () => {
    await initAppState(dispatch, getState);
  }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:15:45