带有用于 SSR 的 redux-toolkit 的 NextJs 应用程序路由器在导航后未设置为初始状态

问题描述 投票:0回答:2

我有一个使用 NextJs 和

app
路由器的简单项目,我还使用
redux/redux-toolkit
进行状态管理,但我遇到了一些小问题。

当我在“page1”上填充 redux 状态,并且用户导航到“page2”时,即使我没有在“page2”上获取这些数据,在“page1”上获取的数据仍然存在于 redux 状态中。同样的事情,当用户从“page2”返回到“page1”时,我在“page2”上获取的数据仍然存在于 redux 状态。

为了让您了解我的意思,我创建了这个简单的 CodeSandbox,您可以在其中检查。 https://codesandbox.io/p/devbox/nextjs-redux-toolkit-z5x2tw

我使用

<a>
标签进行导航,因为这个想法是在用户每次导航到不同页面时获取数据。当用户导航到“Pokemons”时,我们填充
pokemons
状态,当用户导航到“Pokemon”(不带“s”)时,我们仅获取并填充
pokemon
(不带“s”)状态。

我们期望每次用户导航到不同页面时,redux 状态都应该返回到初始状态,因为我们不使用持久状态库或将状态保存到任何存储中。我相信这应该是 redux/redux-toolkit 的默认行为,还是我错过了什么?

javascript reactjs next.js redux redux-toolkit
2个回答
0
投票

您正在服务器端维护 Redux 状态,因此客户端所做的任何事情都有点无关紧要,无论是否是单页应用程序。如果您希望在导航到详细信息页面时将

pokemons
状态重置为
[]
,并在导航到主页时将
pokemon
状态重置为
{}
,这些是您需要管理的状态更改当这些特定操作在减速器中调度和处理时,您自己手动手动操作。

示例:

const initialState: IGlobal = {
  name: "pokeapi.co",
  versionHash:
    versionHashEnv.length > 5 ? versionHashEnv.substring(0, 5) : versionHashEnv,
  loading: false,
  pokemon: {},
  pokemons: [],
};

export const global = createSlice({
  name: "global",
  initialState,
  reducers: {
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.loading = action.payload;
    },
    setPokemon: (state, action: PayloadAction<IPokemon | {}>) => {
      state.pokemon = action.payload;
      state.pokemons = []; // <-- reset when setting pokemon data
    },
    setPokemons: (state, action: PayloadAction<IPokemons | []>) => {
      state.pokemons = action.payload;
      state.pokemon = {}; // <-- reset when setting pokemons array data
    },
  },
});

0
投票

我可以确认 NextJs 状态在每个用户导航中都是持久的。如果您使用

createContext
useContext
钩子,这可以通过
import { unstable_noStore } from 'next/cache';
文档此处 来解决,不过,这不适用于 Redux。即使使用
templates.(js/tsx)
文档,商店仍然会变得持久。

为了解决这个问题,我在每个切片上添加一个

revertAll
操作,然后在每个页面上调用它以在每个导航上重置商店。我不确定这是否是正确的方法,但这解决了我的担忧。示例代码如下:

redux/slice/global.ts

export const global = createSlice({
  name: "global",
  initialState,
  extraReducers(builder: any) {
    builder.addCase(revertAll, () => initialState);
    ...
  },
  reducers: {
    ...
  },
});

然后调用此函数以在每次用户导航时恢复商店

app/page.tsx

async function getData() {
  reduxStore.dispatch(revertAll());
  ...
}

export default async function Page() {
  await getData();
  ...
  }

我希望这可以帮助有同样担忧的人。谢谢你。

© www.soinside.com 2019 - 2024. All rights reserved.