gpt4 book ai didi

reactjs - Next.js:减少数据获取并在页面之间共享数据

转载 作者:行者123 更新时间:2023-12-03 07:35:22 26 4
gpt4 key购买 nike

我正在寻找在 Next.js 应用程序中更好地获取数据的解决方案。在这个问题中,我不只是在寻找解决方案,而是在寻找多种选择,以便我们了解利弊。

我遇到的问题

现在我有几个页面都包含一个显示 som 静态内容的组件和一个具有从 API 获取的一些动态内容的组件。每页做一个fetch()在他们的getInitialProps()获取自己的页面数据,还有页脚数据,所有页面都相同 .

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

我正在寻找的答案

我不只是想解决这个问题,我也在寻找一个概述,以便为 future 的项目学习一些新的实践。我喜欢写“显而易见”的代码,所以不要寻找太老套的解决方案,比如写信给 window对象等。首选具有较少依赖性的简单解决方案。目标是一个快速的网站。减少网络使用/API 调用并不那么重要。

到目前为止我的想法

这是我想出的可能的解决方案,从简单/明显到更复杂。

  • 在 Footer 组件(客户端)内执行 fetch
  • 在所有/pages
  • 上获取 getInitialProps(服务器端和客户端)
  • 使用 HOC 在 _app.js 中进行 fetch 并连接到它的 getInitialProps()并将其添加到 Prop 中,因此所有页面都可以使用数据
  • 使用 zeit/swr 和数据预取来缓存数据
  • 使用 redux 存储全局状态

  • 所有这些“工作”,但其中大多数将不必要地重新获取数据,和/或增加一点复杂性。这是我所看到的优点/缺点(数字与上面相同):
  • 👍 简单!获取代码只在一个地方,它位于使用它的地方。 👎 页面加载后获取数据,因此内容“跳转”到查看。一直在重新获取数据。
  • 👍 简单!数据是在服务器上获取的,因此在呈现页面之前内容是可用的。 👎 为每个页面重新获取数据。我们必须记住为它们的getInitialProps() 中的每个页面获取相同的页脚数据。 .
  • 👍 我们可以在一个地方进行提取并将其添加到所有页面 Prop 中,因此页脚数据自动适用于所有页面的 Prop 。 👎 对于某些人来说,要轻松理解正在发生的事情可能有点复杂,因为它需要更多地了解 Next.js/React 的工作原理。仍然重新获取所有页面的数据。我们现在做两个 fetch()相互调用(首先在 _app.js 中加载页脚内容,然后在每个页面中获取自定义内容),因此速度更慢。
  • 👍 有点简单。我们甚至可以在加载 JS 之前使用预取来加载数据到缓存。第一个页面加载后,我们将快速获取数据。可以直接在页脚组件中获取代码。 👎 rel="preload"预取技术不适用于所有类型的提取(例如 Sanity 的客户端使用 groq)。为了在初始页面加载后加载数据的地方没有“跳跃”内容,我们应该提供 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

    希望对此有更多的了解。我缺少明显的东西?

    最佳答案

    对了!我在寻找其他东西时发现了这个线程。但由于我不得不处理类似的问题,我可以给你一些方向,我会尽力为你说清楚。
    因此,您希望在您的应用程序(页面/组件)中共享一些数据。

  • Next.js 使用 App 组件来初始化页面。您可以覆盖它并控制页面初始化。要实现这一点,只需创建 _app.js pages 根目录下的文件目录。欲了解更多信息,请点击此链接:https://nextjs.org/docs/advanced-features/custom-app
  • 就像您可以使用 getInitialProps 的方式一样在您的页面中从您的 API 获取数据,您也可以在 _app.js 中使用相同的方法.所以,我会获取那些我需要在我的应用程序中共享它们的数据,并消除我的 API 调用。

  • Well, Now I can think of two ways to share the data across my app


  • 使用 createContext钩子(Hook)。

  • 1.1。使用 createContext Hook 创建 DataContext。并包装 <Component {...pageProps} />与您的 <DataContext.Provider> .
    这是一个代码片段,可以为您提供更好的线索:
    <DataContext.Provider value={{ userData, footerData, etc... }}>
    <Component {...pageProps} />
    </DataContext.Provider>
    1.2.现在在其他页面/组件中,您可以访问您的 DataContext,如下所示:
    const { footerData } = useContext(DataContext); 
    然后你就可以在你的前端进行操作了
  • 填充 props使用 getInitialProps

  • 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.现在在您的页面中(而不是在您的组件中),您可以访问 Prop ,包括您从 _app.js 共享的 Prop 。
    然后你就可以开始操作了。
    希望我能给你一个线索和方向。尽情探索吧。

    关于reactjs - Next.js:减少数据获取并在页面之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60899880/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com