我正在寻找在 Next.js 应用程序中更好地获取数据的解决方案。在这个问题上我不只是在寻找一个解决方案,我正在寻找多种选择,所以我们可以看一下利弊。
我遇到的问题
现在我有几个页面,它们都包含一个显示静态内容的组件和一个从 API 获取的一些动态内容的组件。每个页面都做一个fetch()
在他们getInitialProps()
自己的页面数据中,还有页脚数据,这对所有页面都是一样的。
这当然有效,但有很多重复的数据提取。页脚数据将始终为所有页面显示并且始终相同。它也很少在 API 中更改,因此无需重新验证数据。
我正在寻找的答案
我不只是想解决这个问题,我也在寻找一个概述,以便为未来的项目学习一些新的实践。我喜欢编写“明显”的代码,所以不寻找太hacky的解决方案,比如写入window
对象等。优先考虑依赖较少的简单解决方案。目标是一个快速的网站。减少网络使用/API 调用并不是那么重要。
到目前为止我的想法
这是我想出的可能的解决方案,从简单/明显到更复杂。
- 在页脚组件(客户端)内执行提取
- 在所有 /pages 上的 getInitialProps(服务器端和客户端)中获取
- 在 _app.js 中使用 HOC 进行 fetch 并挂钩并将其
getInitialProps()
添加到 props,因此数据可用于所有页面 - 使用 zeit/swr 和数据预取来缓存数据
- 使用 redux 存储全局状态
所有这些“工作”,但其中大多数会不必要地重新获取数据,和/或增加一点复杂性。以下是我所看到的优缺点(数字与上面相同):
- 👍简单!提取代码仅在一处,它位于使用它的地方。👎 页面加载后获取数据,因此内容“跳转”到查看。数据一直在重新获取。
- 👍简单!在服务器上获取数据,因此在呈现页面之前内容可用。👎 为每个页面重新获取数据。我们必须记住为他们的
getInitialProps()
. - 👍 我们可以在一个地方进行 fetch 并将其添加到所有页面 props,因此页脚数据可自动用于所有页面的 props。👎 对于某些人来说,可能会更复杂一些,以便轻松理解正在发生的事情,因为它需要对 Next.js/React 的工作原理有更多的了解。仍然重新获取所有页面的数据。我们现在
fetch()
依次进行两次调用(首先在 _app.js 中加载页脚内容,然后在每个页面中获取自定义内容),所以它甚至更慢。 - 👍 有点简单。我们甚至可以在加载 JS 之前使用预取将数据加载到缓存。在第一页加载后,我们将有快速的数据获取。可以直接在页脚组件中获取代码。👎
rel="preload"
预取技术不适用于所有类型的提取(例如使用 groq 的 Sanity 客户端)。要对数据进行页面加载完成后加载没有“跳跃”的内容,我们应该提供useSWR()
具有initialData
仍需要我们在获取数据getInitialProps()
,但它是不够的,只是做在服务器端。可以用新的getServerSideProps()
。 - 👍 我们可以加载一次数据(?),并在整个应用程序中都可用。快速且更少/无需重新获取。👎 添加外部依赖。更复杂的是你必须学习 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
希望对此有更多的了解。我缺少一些明显的东西?