【问题标题】:Is it possible to prevent getServerSideProps causing a full page reload after initial load?是否可以防止 getServerSideProps 在初始加载后导致整个页面重新加载?
【发布时间】:2022-01-22 07:32:48
【问题描述】:

我有一个服务器渲染的 next.js 应用程序,它是一个 3 页的结帐流程。在第一页,我正在获取getServerSideProps 中的各种设置数据,例如标签翻译和购物篮项目,如下所示:

UserDetails.js

import React from 'react';
import { LabelsContext } from "../contexts";
import { Component1, Component2 } from '../components'

const UserDetails = () => {
  const labels = useContext(LabelsContext);

  return (
    <div>
      <Component1 labels={labels} />
      <Component2 labels={labels} />
    </div>
  )
}

export const getServerSideProps = async (context) => {
  const {
    locale,
    basketId,
  } = context.res.locals;

  const { cookie } = context.req.headers;

  const graphQLClient = new GraphQLClient(
    GRAPHQL_ENDPOINT,
    {
      headers: {
        'Content-Language': locale,
        'X-Basket': basketId,
        cookie,
      },
    },
  );

  const { labels } = await graphQLClient.request(getLabels);

  return {
    labels,
    locale,
  };
};

export default UserDetails;

然后,此数据从 pageProps 传递到 _app.js 中的本地状态,并从那里传递到上下文提供程序:

_app.js

import React from 'react';
import { useApollo } from '@apollo/client';

const App = ({ Component, pageProps }) => {
  const [labels, setLabels] = useState(pageProps.labels);

  const apolloClient = useApollo(pageProps.initialApolloState);

  return (
    <ApolloProvider client={apolloClient}>
      <LabelsContext.Provider value={labels}>
        <Component {...pageProps} />
      </LabelsContext.Provider>
    </ApolloProvider>
  );
};

这在初始渲染中运行良好,因为提取成功并且设置为_app.js 状态的数据意味着它们可用于流中的后续页面。但我的问题是,当用户从第 2 页单击浏览器后退按钮回到 UserDetails 页面时,它会再次执行完整页面重新加载以重新获取数据。重新获取数据不是什么大问题,但是当页面重新加载时,表单中输入的所有数据都会丢失。此外,当所有其他页面转换都是快速的客户端加载时,用户体验有点不和谐。

一旦页面已经加载过一次,有没有办法防止在这种情况下重新加载整个页面?

谢谢大家。

【问题讨论】:

  • 仅从您的代码不清楚为什么从第二页返回到UserDetails 页面会触发整个页面重新加载。这需要进一步调试,因为这不是预期的行为。当您实际按下后退按钮时,您是否在开发工具Network 选项卡中看到任何失败的请求?即为UserDetails获取JSON数据的请求?
  • @juliomalves 是的,我确实看到 UserDetails.json 失败了。你知道为什么会这样吗?
  • 请求 URL 是什么样的?而且,您是否有机会在您的next.config.js 中使用assetPrefix
  • @juliomalves 请求 URL 是 http://localhost:3000/_next/data/development/co/details.json,我在 next.config.js 中有 assetPrefix: '/co/',
  • 太完美了,谢谢!我找了很久,但没有看到那个问题!感谢您的帮助@juliomalves

标签: javascript reactjs next.js server-side-rendering


【解决方案1】:

由于在客户端转换期间检索 UserDetails 页面的 JSON 数据的请求失败,所以会重新加载整个页面。

在您的next.config.js 中添加assetPrefix 条目将产生以下效果:

Next.js 将自动将您的资产前缀用于它从 /_next/ 路径加载的 JavaScript 和 CSS 文件。

但是,在客户端上检索 JSON 数据时,资产前缀影响来自 getServerSideProps/_next/data/ 请求,这意味着这些请求将 404,进而触发整个页面重新加载(如你正在经历)。

解决方案是使用basePath 而不是assetPrefix。这允许您为整个应用程序设置路径前缀,其中包括getServerSideProps 为检索页面的 JSON 数据而发出的请求。


目前,除了使用 basePath 之外别无选择,因为它是向 /_next/data/ 请求添加前缀的唯一方法。但是,有一个关于这个问题的公开讨论:https://github.com/vercel/next.js/discussions/25681

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 2016-06-08
    • 2015-07-04
    • 2011-07-09
    • 1970-01-01
    相关资源
    最近更新 更多