首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在客户端导航中保留状态值- NextJs -Next-Redux-包装器

在客户端导航中保留状态值- NextJs -Next-Redux-包装器
EN

Stack Overflow用户
提问于 2021-04-08 20:42:10
回答 1查看 2.1K关注 0票数 4

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

截图从redux tools Hydrate action diff:

截图是在从主页路由到产品页面后拍摄的,这样就有了一个现有的商店。一切都被重置为初始的应用程序状态。

我想做的是

在store.js中,我创建了存储,并预见了一个还原器来处理Hydrate调用。这种方法的缺点是有效负载始终是一个新的存储对象,因为它是在服务器上调用的。我正在考虑检查2 json之间的差异,然后只应用差别,而不是整个初始商店。

客户端状态和服务器状态之间的差异。state.

  • Currently

  • 创建下一个状态,用修补的服务器状态覆盖客户端状态,这包括水合物的更新状态和现有的客户端

  • 生成一个白色页面。

您可以在store.js中看到下面的还原器代码

代码语言:javascript
运行
复制
//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;
代码语言:javascript
运行
复制
//_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));
代码语言:javascript
运行
复制
// 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;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-12 10:10:33

好吧,所以我解决了我的问题通过不过度思考的概念。回到画板上,做了一个简单的解决方案。

得出的结论是,只有少数状态对象需要在客户端导航期间持久化。

我只需要对我的i18n做一个更改,就可以使它变得动态,因为我们在页面的基础上获取翻译。

这是任何可能在将来遇到类似问题的人的最后一种还原剂。

代码语言:javascript
运行
复制
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);
};
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67011597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档