因此,我试图解决我在使用wrapper.getServerSideProps时面临的水化问题。当我重新安排当前的设置时,存储将被清除,然后添加新的数据,这将导致一个白页,因为许多重要的数据不再存在(即翻译和cms数据)。
截图从redux tools Hydrate action diff:

截图是在从主页路由到产品页面后拍摄的,这样就有了一个现有的商店。一切都被重置为初始的应用程序状态。
我想做的是
在store.js中,我创建了存储,并预见了一个还原器来处理Hydrate调用。这种方法的缺点是有效负载始终是一个新的存储对象,因为它是在服务器上调用的。我正在考虑检查2 json之间的差异,然后只应用差别,而不是整个初始商店。
客户端状态和服务器状态之间的差异。state.
。
您可以在store.js中看到下面的还原器代码
//store.js
import combinedReducer from './reducer';
const bindMiddleware = (middleware) => {
    if (process.env.NODE_ENV !== 'production') {
        return composeWithDevTools(applyMiddleware(...middleware));
    }
    return applyMiddleware(...middleware);
};
const reducer = (state, action) => {
  if (action.type === HYDRATE) {
    const clientState = { ...state };
    const serverState = { ...action.payload };
    if (state) {
      // preserve state value on client side navigation
      // Get the difference between the client and server state.
      const diff = jsondiffpatch.diff(clientState, serverState);
      if (diff !== undefined) {
        // If there is a diff patch the serverState, with the existing diff
        jsondiffpatch.patch(serverState, diff);
      }
    }
    // Make next state, overwrite clientstate with patched serverstate
    const nextState = {
      ...clientState,
      ...serverState,
    };
    // Result, blank page.
    return nextState;
  }
  return combinedReducer(state, action);
};
export const makeStore = () => {
    const cookies = new Cookies();
    const client = new ApiClient(null, cookies);
    const middleware = [
        createMiddleware(client), 
        thunkMiddleware.withExtraArgument(cookies),
    ];
    return createStore(reducer, bindMiddleware(middleware));
};
const wrapper = createWrapper(makeStore);
export default wrapper;//_app.jsx
const App = (props) => {
    const { Component, pageProps, router } = props;
    return (
        <AppComponent cookies={cookies} locale={router.locale} location={router}>
            <Component {...pageProps} />
        </AppComponent>
    );
};
App.getInitialProps = async ({ Component, ctx }) => {
    return {
        pageProps: {
            ...(Component.getInitialProps ? await Component.getInitialProps(ctx) : {}),
        },
    };
};
App.propTypes = {
    Component: PropTypes.objectOf(PropTypes.any).isRequired,
    pageProps: PropTypes.func,
    router: PropTypes.objectOf(PropTypes.any).isRequired,
};
App.defaultProps = {
    pageProps: () => null,
};
export default wrapper.withRedux(withRouter(App));// Product page
export const getServerSideProps = wrapper.getServerSideProps(
async ({ query, store: { dispatch } }) => {
    const productCode = query.id?.split('-', 1).toString();
    await dispatch(getProductByCode(productCode, true));
});
const PDP = () => {
    const { product } = useSelector((state) => state.product);
    return (
        <PageLayout>
            <main>
                <h1>{product?.name}</h1>
                <div
                    className="description"
                    dangerouslySetInnerHTML={{ __html: product?.description }}
                />
            </main>
        </PageLayout>
    );
};
export default PDP;发布于 2021-04-12 10:10:33
好吧,所以我解决了我的问题通过不过度思考的概念。回到画板上,做了一个简单的解决方案。
得出的结论是,只有少数状态对象需要在客户端导航期间持久化。
我只需要对我的i18n做一个更改,就可以使它变得动态,因为我们在页面的基础上获取翻译。
这是任何可能在将来遇到类似问题的人的最后一种还原剂。
const reducer = (state, action) => {
  if (action.type === HYDRATE) {
    const clientState = { ...state };
    const serverState = { ...action.payload };
    const nextState = { ...clientState, ...serverState };
    const locale = nextState.i18n.defaultLocale || config.i18n.defaultLocale;
    const nextI18n = {
      ...state.i18n,
      locale,
      messages: {
        [locale]: {
          ...state.i18n.messages[locale],
          ...nextState.i18n.messages[locale],
        },
      },
      loadedGroups: {
        ...state.i18n.loadedGroups,
        ...nextState.i18n.loadedGroups,
      },
    };
    if (state) {
      nextState.i18n = nextI18n;
      nextState.configuration.webConfig = state.configuration.webConfig;
      nextState.category.navigation = state.category.navigation;
    }
    return nextState;
  }
  return combinedReducer(state, action);
};https://stackoverflow.com/questions/67011597
复制相似问题