Js:减少数据提取并在页面之间共享数据 [英] Next.js: Reduce data fetching and share data between pages

查看:7
本文介绍了Js:减少数据提取并在页面之间共享数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找在Next.js应用程序中更好地获取数据的解决方案。在这个问题中,我不仅在寻找解决方案,我还在寻找多个选项,以便我们可以看到利弊。

我遇到的问题

现在我有几个页面,它们都包括一个显示一些静态内容的组件和一个具有从API获取的一些动态内容的组件。每个页面在其getInitialProps()中执行fetch()以获取自己的页面数据和页脚数据,对所有页面都是相同的

这当然是可行的,但有很多重复的数据获取。页脚数据将始终为所有页面显示,并且始终相同。它在API中也很少更改,因此不需要重新验证数据。

我正在寻找的答案

我不仅希望解决这一个问题,我还希望获得一个概述,以便为未来的项目学习一些新的实践。我喜欢写"显而易见的"代码,所以不去寻找过于繁琐的解决方案,比如写window对象等。简单的解决方案依赖程度较低。我们的目标是建立一个快速的网站。减少网络使用量/API调用并不那么重要。

我到目前为止的想法

这是我提出的可能的解决方案,从简单/显而易见到更复杂。

  1. 在页脚组件(客户端)内执行提取
  2. 在所有/Pages上的getInitialProps(服务器端和客户端)中执行提取
  3. 使用临时对象Fetch in_app.js并挂钩到它的getInitialProps()并将其添加到道具中,这样所有页面都可以使用数据
  4. 使用Zeit/SWR和数据预取来缓存数据
  5. 使用redux存储全局状态

所有这些"工作",但它们中的大多数将不必要地重新获取数据,和/或增加一点复杂性。以下是我认为的利弊(数字同上):

  1. 👍简单!取码只在一个地方,它位于它被使用的地方。👎数据是在页面加载后提取的,因此内容会"跳"到视图中。数据一直在刷新。
  2. 👍简单!数据是在服务器上提取的,因此内容在呈现页面之前就可用。为每一页重新获取👎数据。我们必须记住为getInitialProps()中的每个页面获取相同的页脚数据。
  3. 👍我们可以在一个位置进行提取并将其添加到所有页面道具,因此页脚数据自动可用于所有页面道具。对于一些人来说,👎可能要更复杂一些才能容易地理解发生了什么,因为它需要更多地理解Next.js/Reaction是如何工作的。仍然重新获取所有页面的数据。我们现在相继执行两个fetch()调用(首先在_app.js中加载页脚内容,然后在每个页面中获取定制内容),因此速度更慢。
  4. 👍有点简单。我们甚至可以在加载JS之前使用预取将数据加载到缓存。在第一个页面加载后,我们将有快速的数据获取。可以在页脚组件中直接获取代码。👎rel="preload"预取技术并不适用于所有类型的获取(例如,Sanity的客户端使用groq)。为了避免在初始页面加载后加载数据的"跳跃"内容,我们应该为useSWR()提供initialData,这仍然需要我们在getInitialProps()中获取数据,但只在服务器端这样做就足够了。可以使用新的getServerSideProps()
  5. 👍我们只需加载一次数据(?)并使其在整个应用程序中可用。快速和更少/不需要重新提取。👎增加了外部依赖。更复杂,因为您必须学习redux,即使只加载一个共享数据对象也是如此。

当前解决方案,使用项目符号编号2中描述的解决方案。

const HomePage = (props) => {
  return (
    <Layout data={props.footer}>
       <Home data={props.page} />
    </Layout>
  )
}

// Not actual query, just sample
const query = `{
  "page": *[_type == "page"][0], 
  "footer": *[_type == "footer"][0]
}`

HomePage.getInitialProps = async () => {
  const data = await client.fetch(query)

  return {
    page: data.page
    footer: data.footer
  }
}

export default HomePage

想要更深入地了解这一点。我明显漏掉了什么?

推荐答案

O‘Right!我在找别的东西的时候发现了这个帖子。但既然我要处理类似的问题,我可以给你一些指导,我会尽我所能为你澄清。

因此,您希望在您的应用程序(页面/组件)之间共享某些数据。

  1. Next.js使用App组件初始化页面。您可以重写它并控制页面初始化。要实现这一点,只需在pages目录的根目录中创建_app.js文件。有关更多信息,请访问此链接:https://nextjs.org/docs/advanced-features/custom-app
  2. 就像您可以在页面中使用getInitialProps从API获取数据一样,您也可以在_app.js中使用相同的方法。因此,我会获取我需要的数据,以便在我的应用程序中共享它们,并消除我的API调用。

好的,现在我可以想出两种方法在我的应用程序中共享数据

  1. 使用createContext挂钩。

1.1。使用createContext挂钩创建一个DataContext。并用<DataContext.Provider><Component {...pageProps} />括起来。 以下是一段代码片段,可以为您提供更好的线索:

<DataContext.Provider value={{ userData, footerData, etc... }}>
  <Component {...pageProps} />
</DataContext.Provider>

1.2。现在,在其他页面/组件中,您可以访问数据上下文,如下所示:

const { footerData } = useContext(DataContext); 

然后您就可以在您的前端进行操作

  1. 使用getInitialProps填充props

2.1。getInitialProps用于异步获取一些数据,然后填充props。这与_app.js中的情况相同。

_app.js中的代码如下所示:

function MyApp({ Component, pageProps, footerData }) {
  //do other stuffs
  return (
   <Component {...pageProps} footerData={footerData} />
  ;
}

MyApp.getInitialProps = async ({ Component, ctx }) => {
  const footerRes = await fetch('http://API_URL');
  const footerData = await footerRes.json(); 
  let pageProps = {};
  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx);
  }
  return { pageProps, footerData };
};

2.2。现在,在您的页面中(而不是在您的组件中),您可以访问道具,包括您从分享的道具 你就可以开始操控了。

希望我能给你一点提示和方向。祝您探索愉快。

这篇关于Js:减少数据提取并在页面之间共享数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆