NextJS:有没有一种方法可以仅在服务器端、仅在新页面加载时调用某些内容?

tun*_*ith 5 reactjs next.js react-hooks

我们的团队最初创建了一个_app.tsxwith getInitialProps,并包含了类似的内容

if (!req) return {};
Run Code Online (Sandbox Code Playgroud)

作为顶线。这个想法是getInitialProps仅在服务器端运行,仅在初始页面加载时运行。我们认为这是一个安全的假设,因为通常的建议(经常在 stackoverflow 答案中重复)是getInitialProps在页面转换时在客户端运行。

我们后来发现getInitialProps,如果您要转换到具有getServerSideProps.

所以这不符合我们的目的 - 我们有几个网络查询,这些查询是getInitialProps在我们的大多数页面转换上进行的(因为我们的大多数页面都有getServerSideProps),而我们的目的是只在新页面上运行这些查询(应用程序)加载。

我们可以useEffect只在组件安装上使用,但我们希望在服务器端而不是客户端运行这些查询,以防止视觉闪烁。

我正在学习如何设置一个上下文,其中包含 setState,但初始测试显示其初始 setState 在客户端和服务器端运行:

...

const getString = (): string => {
  console.log('about to set string!');
  return 'string';
};

const PagePropsProvider: React.FC<IProps> = ({ pageProps, children }) => {
  const [sample, setSample] = useState<string>(getString());

  return <PagePropsContext.Provider value={pageProps}>{children}</PagePropsContext.Provider>;
};
...

Run Code Online (Sandbox Code Playgroud)

对于像身份验证上下文这样的东西,我想要的是_app.tsxgetInitialProps页面加载时请求初始用户对象服务器端,将其从道具提供给上下文,而不是让应用程序重新请求初始用户对象不必要在每个页面转换时进行。如果我可以阻止getInitialProps在页面转换上运行,我就可以做到这一点。有没有办法阻止getInitialProps在这些页面转换上运行?或者以更惯用的方式来实现我们的目标?(理想情况下,我们希望getInitialProps完全避免,但同样的问题仍然存在getServerSideProps,如何使其仅在新页面加载时调用。)

tun*_*ith 6

通过仔细检查和context中的对象,我注意到一个元素似乎可靠地指示了客户端页面转换和新页面加载之间的差异:客户端页面转换似乎总是以开头- 即使代码本身(或)正在服务器端运行。getInitialPropsgetServerSidePropscontext.req.url/_next/datagetInitialPropsgetServerSideProps

所以我们正在尝试如下代码:

if (!req || (req.url && req.url.startsWith('/_next/data'))) {
  // return early
}
...
Run Code Online (Sandbox Code Playgroud)

我不确定这对于未来的版本是否可靠或“支持”,因此我还在此处提出了功能请求:

https://github.com/vercel/next.js/discussions/19459