javascript - Redux 工具包存储在下一个 js 中的页面之间导航时自动重置

标签 javascript reactjs redux next.js redux-toolkit

我是一个新的 Next 用户,并且长期以来一直在使用 Redux 和 React
我在使用 Redux 和 Next 时遇到了很多麻烦
我已经完成了这个解决方案
store.js

import { configureStore } from '@reduxjs/toolkit';
import reducers from './rootReducer';

export function makeStore() {
  return configureStore({
    reducer: reducers,
  });
}

const store = makeStore();

export default store;
rootReducer.js
import { combineReducers } from '@reduxjs/toolkit';
import tes from './test/tes';

const reducers = combineReducers({
  test: tes,
});

export default reducers;
_app.js
import React from 'react';
import { Provider } from 'react-redux';
import store from '../redux/store';
import { createWrapper } from 'next-redux-wrapper';

const MyApp = ({ Component, ...rest }) => {
  return (
    <Provider store={store}>
      <Component {...rest} />
    </Provider>
  );
};
const makestore = () => store;
const wrapper = createWrapper(makestore);

export default wrapper.withRedux(MyApp);
但我发现任何使用 useDispatch
在任何页面内,搜索引擎在获取数据后无法识别页面内容
import React, { useEffect } from 'react';
import { Test } from '../../redux/test/tes';
import { useDispatch, useSelector } from 'react-redux';
import Link from 'next/link';

function TestPage() {
  const dispatch = useDispatch();
  const { data } = useSelector((state) => state.test);
  useEffect(() => {
    dispatch(Test('hi'));
  }, []);
  return (
    <div>
      <Link href="/">
        <a>home</a>
      </Link>{' '}
      {data.map((name) => (
        <h1>{name.title}</h1>
      ))}
    </div>
  );
}

export default TestPage;
必须使用下一个预渲染方法之一
我想知道下一个 是否正常
或者有更好的方法吗?

#1 更新
现在将数据提取移至 getStaticProps TestPage.js
import React from 'react';
import { Test } from '../../redux/test/tes';
import {  useSelector } from 'react-redux';
import Link from 'next/link';
import { wrapper } from '../../redux/store';

function TestPage({ pageProps }) {
  const { data } = useSelector((state) => state.test);
  console.log(data);

  return (
    <div>
      <Link href="/">
        <a>home</a>
      </Link>{' '}
      {data && data.map((name) => (
        <h1>{name.name}</h1>
      ))}
    </div>
  );
}
export const getStaticProps = wrapper.getStaticProps(
  (store) => async (context) => {
    const loading = store.getState().test.loading;
    if (loading === 'idle') {
      await store.dispatch(Test('hi'));

    }

    return {
      props: {  },
    };
  }
);

export default TestPage;
现在的问题是商店没有更新useSelector return [] 虽然 console.log (data)从 getStaticProps 数据存在__NEXT_REDUX_WRAPPER_HYDRATE__我被困住了

#2 更新
到达这里真的很难,在那之后,使用 Next js 获取 Redux 仍然存在问题
现在一切正常,直到导航到任何页面有 getStaticPropsgetServerProps状态自动重置
store.js
import reducers from './rootReducer';
import { configureStore } from '@reduxjs/toolkit';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';

const reducer = (state, action) => {
  if (action.type === HYDRATE) {
    let nextState = {
      ...state,
      ...action.payload,
    };
    return nextState;
  } else {
    return reducers(state, action);
  }
};

const isDev = process.env.NODE_ENV === 'development';

const makeStore = (context) => {
  let middleware = [];

  const store = configureStore({
    reducer,
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(middleware),
    devTools: isDev,
    preloadedState: undefined,
  });

  return store;
};

export const wrapper = createWrapper(makeStore, { debug: isDev });

最佳答案

最后,这种方式只管用
甚至服务器和客户端状态分离也不起作用
有了这个jsondiffpatch
rootReducer.js

const rootReducer = createReducer(
  combinedReducers(undefined, { type: '' }),
  (builder) => {
    builder
      .addCase(HYDRATE, (state, action) => {
        const stateDiff = diff(state, action.payload);
        const isdiff = stateDiff?.test?.data?.[0];
        const isdiff1 =
          stateDiff?.test1?.data?.[0] 
        return {
          ...state,
          ...action.payload,

          test: isdiff ? action.payload.test : state.test,
          test1: isdiff1 ? action.payload.test1 : state.test1,
        };
      })
      .addDefaultCase(combinedReducers);
  }
);
这里唯一的问题是你必须测试状态内每一部分的每一个变化
我会在赏金结束之前留下最佳答案,谢谢大家。

更新:
因为一个全局性的水合物还原剂可能是矫枉过正。
这是一个在每个切片中处理水合作用的示例
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { diff } from 'jsondiffpatch';
import { HYDRATE } from 'next-redux-wrapper';

const initialState = {
  data: [],
};
export const TestFetch = createAsyncThunk(
  'TestFetch',
  async (data, { rejectWithValue, dispatch }) => {
    try {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/users'
      );
      const d = await response.json();
      return d;
    } catch (error) {
      return rejectWithValue(error.response.data.error);
    }
  }
);

const test = createSlice({
  name: 'test',
  initialState,
  reducers: {
    update: {
      reducer: (state, { payload }) => {
        return { ...state, data: payload };
      },
    },
  },
  extraReducers: {
    [HYDRATE]: (state, action) => {
      const stateDiff = diff(state, action.payload);
      const isdiff1 = stateDiff?.server?.[0]?.test?.data?.[0];
      // return {
      //   ...state,
      //   data: isdiff1 ? action.payload.server.test.data : state.data,
      // };
      state.data = isdiff1 ? action.payload.server.test.data : state.data;
    },
    [TestFetch.fulfilled]: (state, action) => {
      state.data = action.payload;
    },
  },
});

export const { update } = test.actions;
export default test.reducer;

关于javascript - Redux 工具包存储在下一个 js 中的页面之间导航时自动重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70995389/

相关文章:

reactjs - 使用 Typescript 和 Redux Toolkit 后在 createAsyncThunk 函数中获取 'Object is of type unknown'

javascript - 在代理数组上调用 concat 会引发错误

javascript - meteor JS : What is the best way to store states for a specific template instance?

javascript - 找到两个哈希数组的差异

javascript - 如何在 react 中用 Jest 和 enzyme 测试表单提交?

reactjs - 如何在 React Material-UI 中动态更改 GridList 的列

javascript - 在我通过 props 的 React Enzyme 单元测试中设置状态

javascript - 将 Google map DIV 转换为图像

javascript - 定位环绕 radio 输入的跨度

javascript - 将谷歌日历 API 集成到 React hooks