Next.js:在 getInitialProps() 中获取数据:服务器端与客户端

Posted

技术标签:

【中文标题】Next.js:在 getInitialProps() 中获取数据:服务器端与客户端【英文标题】:Next.js: fetching data in getInitialProps(): server-side vs client-side 【发布时间】:2018-08-31 03:05:58 【问题描述】:

我正在使用 Next.js,并且我有一个使用 Express 的自定义服务器。我有一个页面需要数据库中的一些数据。

getInitialProps(),在服务器上运行时,可以从数据库中抓取数据并返回,没有任何问题。 但是,getInitialProps() 也可以在客户端运行(当用户最初请求不同的页面,然后导航到该页面时)。在这种情况下,由于我在客户端,我显然不能只从数据库中获取数据 - 我必须使用 AJAX 与服务器通信并要求它为我检索它。

当然,这也意味着我已经在服务器上定义了一个新的 Express 路由来处理这个请求,它会包含与getInitialProps() 的服务器端部分完全相同的代码,这是非常不可取的。

处理这个问题的最佳方法是什么?

【问题讨论】:

【参考方案1】:

getInitialProps() 总是将请求和响应作为仅在服务器上设置的参数接收:

static async getInitialProps(req)
 if(req)
   // called on server
  else 
   // called on client
 

https://github.com/zeit/next.js#fetching-data-and-component-lifecycle

【讨论】:

我知道,但这并不能解决我的问题。 如果我按照解决方案在服务器中而不是在客户端中进行我的 api 调用,它会导致任何问题吗?为什么 getInitialProps() 会在服务器和客户端被调用两次? 由于 getInitialProps 有时也会在浏览器中运行,因此请确保其中不包含密码,即使在 if(req) 子句中也是如此【参考方案2】:

由于似乎没有好的解决方案,我创建并发布了一个库来为这个问题提供一个简单而优雅的解决方案:next-express。

【讨论】:

【参考方案3】:

在您的getInitialProps 中,您应该向具有从数据库中获取逻辑的新快速路由发出 http 请求。该逻辑不应该存在于 UI 层中。

无论您是在客户端还是在服务器上,都应该调用此路由 - 您不需要进行任何代码分支。

【讨论】:

【参考方案4】:

使 API 与您的 next.js 应用程序不同。将下一个应用程序视为恰好在服务器上呈现页面的前端客户端

【讨论】:

【参考方案5】:

随着时间的推移,新的解决方案会出现。 Nextjs 引入了一种新方法getServerSideProps 主要针对此类用例

getServerSideProps only runs on server-side and never runs on the browser. 

【讨论】:

getServerSideProps(),似乎只有在下一个 9.3.0 之后才可用,我使用的是 9.0.2 并坚持使用 getInitialProps()。有解决办法吗? @Vishu 您应该可以升级您的版本,最好使用它们,因为这将是一个长期解决方案【参考方案6】:

对我来说,我发现最快的方法是从__NEXT_DATA__获取数据

MyApp.getInitialProps = async (): Promise<AppCustomProps> => 
  const isInBroswer = typeof window !== 'undefined';
  if (isInBroswer) 
    const appCustomPropsString =
      document.getElementById('__NEXT_DATA__')?.innerhtml;

    if (!appCustomPropsString) 
      throw new Error(`__NEXT_DATA__ script was not found`);
    

    const appCustomProps = JSON.parse(appCustomPropsString).props;
    return appCustomProps;
  

// server side, where I actually fetch the data from db/cms and return it

【讨论】:

以上是关于Next.js:在 getInitialProps() 中获取数据:服务器端与客户端的主要内容,如果未能解决你的问题,请参考以下文章

Next.js:在 getInitialProps() 中获取数据之前加载的页面

在 Next.js 中,为啥要静态渲染? _document.js 包括 getInitialProps

next.js mapStateToProps、mapDispatchToProps 和 getInitialProps

Next.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面

Next.js:在 getInitialProps() 中获取数据:服务器端与客户端

Next.js文档自定义AppDocument,getInitialProps翻译