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

Reactjs Next.js:减少数据获取并在页面之间共享数据,reactjs,redux,fetch,next.js,sanity,Reactjs,Redux,Fetch,Next.js,Sanity,我正在寻找在Next.js应用程序中更好地获取数据的解决方案。在这个问题上,我不仅仅是在寻找一个解决方案,我在寻找多个选项,这样我们就可以看到利弊 我的问题 现在,我有几个页面,都包含一个显示som静态内容的组件和一个包含一些从API获取的动态内容的组件。每个页面在其getInitialProps()中执行fetch(),以获取自己的页面数据,但也获取页脚数据,,这对于所有页面都是相同的 这当然有效,但是有很多重复的数据获取。页脚数据将始终显示在所有页面上,并且始终相同。它也很少在API中更改,

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

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

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

我在寻找的答案 我不仅仅是想解决这一个问题,我还想了解一些关于未来项目的新实践的概述。我喜欢写“明显”的代码,所以不要寻找太粗糙的解决方案,比如写
窗口
对象等。最好是依赖性较小的简单解决方案。目标是一个快速的网站。减少网络使用/API调用并不重要

到目前为止我的想法是什么 这就是我提出的可能的解决方案,从简单/明显到更复杂

  • 在页脚组件(客户端)内部执行提取
  • 在所有/页上获取getInitialProps(服务器端和客户端)
  • 使用HOC在_app.js中提取数据,并挂接到它的
    getInitialProps()
    ,然后将其添加到props中,这样所有页面都可以使用数据
  • 使用zeit/swr和数据预取来缓存数据
  • 使用redux存储全局状态
  • 所有这些都“起作用”,但其中大多数都会不必要地重新蚀刻数据,和/或增加一点复杂性。以下是我所看到的优点/缺点(数字与上面相同):


  • 好的!我在找别的东西的时候发现了这根线。但是,由于我必须处理类似的问题,我可以给你们一些指导,我将尽我所能为你们澄清

    因此,您希望在应用程序(页面/组件)中共享一些数据

  • Next.js使用应用程序组件初始化页面。您可以覆盖它并控制页面初始化。要实现这一点,只需在
    页面
    目录的根目录中创建
    \u app.js
    文件。有关更多信息,请访问此链接:
  • 就像您可以在页面中使用
    getInitialProps
    从API获取数据一样,您也可以在
    \u app.js
    中使用相同的方法。因此,我将获取我需要在我的应用程序中共享的数据,并消除API调用
  • 现在,我可以想出两种方法在我的应用程序中共享数据

  • 使用
    createContext
    挂钩
  • 1.1。使用createContext挂钩创建DataContext。并用
    包装
    。 下面是一段代码片段,可以为您提供更好的线索:

    <DataContext.Provider value={{ userData, footerData, etc... }}>
      <Component {...pageProps} />
    </DataContext.Provider>
    
    然后你就可以在前端进行操作了

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

    \u 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 };
    };
    
    函数MyApp({Component,pageProps,footerData}){
    //做其他事情
    返回(
    ;
    }
    MyApp.getInitialProps=异步({Component,ctx})=>{
    const footerRes=等待提取('http://API_URL');
    const footerData=wait footerRes.json();
    让pageProps={};
    if(Component.getInitialProps){
    pageProps=等待组件.getInitialProps(ctx);
    }
    返回{pageProps,footerData};
    };
    
    2.2.现在,您可以在页面(而不是组件)中访问道具,包括从
    \u app.js
    你可以开始做你自己的操作


    希望我能给你一个线索和方向。祝你探索愉快。

    如果我想将这些数据传递给导航组件,该怎么办?假设你有一个包含各个组件的索引页。你可以访问索引中的道具,现在你只需要将其传递给组件。这样你就可以像这样轻松地处理它:在H中eader组件您可以拥有子组件,如导航栏,您可以从标题数据中提取数据并将其分配给导航组件。因此,假设标题组件中的数据可能是这样的,希望我能给您一些线索。导航栏是布局的一部分,您的意思是我应该从
    \u app.js从这里我可以将数据传递到组件,对吗?我只是提出了一个问题来解决我的问题,如果你想在那里回答,我会接受。在_应用程序中使用getInitialProps的问题是它会禁用自动静态优化。因此所有页面都将在服务器端呈现,这意味着你错过了页面b的好处静态生成。在Next.js文档中:“注意事项:如果您有一个带有getInitialProps的自定义应用程序,那么此优化将在没有静态生成的页面中关闭。”-为什么使用
    getInitialProps
    ?为什么不使用
    getServerSideProps
    ?顺便说一句,您没有考虑过cookies吗?您可以通过服务器端获取并设置它们
    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 };
    };