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

kwvwclae  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(109)

我是Next的新用户,使用Redux with React已经很长时间了,我在使用Redux with Next时遇到了很多麻烦
我已完成此解决方案

存储.js

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

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

const store = makeStore();

export default store;

根还原器.js

import { combineReducers } from '@reduxjs/toolkit';
import tes from './test/tes';

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

export default reducers;

_应用程序.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之后

测试页面.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 []
尽管getStaticProps提供了console.log (data)数据,但__NEXT_REDUX_WRAPPER_HYDRATE__我卡住了

#2更新

这是真的很难到达这里,在那之后,仍然有问题得到Redux与Next的js
现在一切正常,直到导航到任何页面有getStaticPropsgetServerProps
状态自动复位

存储.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 });
vfhzx4xs

vfhzx4xs1#

最后,这种方式只起作用。甚至服务器和客户端状态分离也不起作用。
我用的是这个jsondiffpatch

根还原器.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;
cunj1qz1

cunj1qz12#

1.)将Redux与Nextjs一起使用是否会消除SEO优势?
不,在NextJS中使用Redux并不妨碍SEO的优势。Redux与NextJS配合得很好。
问题出在你的数据获取实现上。NextJS看不到获取的内容,因为你需要在getInitialPropsgetServerSidePropsgetStaticProps中获取它,这取决于你希望你的应用工作的方式。
请参阅NextJS中的Data Fetching documentation
请注意,getServerSidePropsgetStaticProps是处理数据提取的推荐方式。
如果您选择getStaticProps,您将需要getStaticPaths。请检查此答案以查看使用案例和difference between the getStaticPaths and getStaticProps,因为它可能会让人感到困惑。
TLDR;不要将数据提取放在useEffect挂钩中,而是将其移动到getServerSidePropsgetStaticProps函数中。

相关问题