简体   繁体   English

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

[英]Next.js: fetching data in getInitialProps(): server-side vs client-side

I'm using Next.js, and I have a custom server using Express.我正在使用 Next.js,并且我有一个使用 Express 的自定义服务器。 I have a page that requires some data from the database.我有一个页面需要来自数据库的一些数据。

getInitialProps() , when running on the server, could just grab the data from the database and return it, without any problems. getInitialProps()在服务器上运行时,可以从数据库中获取数据并返回它,没有任何问题。 However, getInitialProps() can also run on the client side (when the user initially requests a different page, then navigates to this one).但是, getInitialProps()也可以在客户端运行(当用户最初请求不同的页面,然后导航到这个页面时)。 In that case, since I'm on the client side, I obviously can't just fetch the data from the database - I have to use AJAX to talk to the server and ask it to retrieve it for me.在这种情况下,由于我在客户端,我显然不能只从数据库中获取数据 - 我必须使用 AJAX 与服务器对话并要求它为我检索它。

Of course, this also means that I have define a new Express route on the server to handle this request, which will contain exactly the same code as the server-side part of getInitialProps() , which is very undesirable.当然,这也意味着我在服务器上定义了一个新的 Express 路由来处理这个请求,它会包含与getInitialProps()的服务器端部分完全相同的代码,这是非常不可取的。

What's the best way to handle this?处理这个问题的最佳方法是什么?

getInitialProps() always receives the request and response as parameters which are only set on the server: 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 https://github.com/zeit/next.js#fetching-data-and-component-lifecycle

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

In your getInitialProps you should be making a http request to a new express route that has your logic for fetching from the database.在您的getInitialProps您应该向新的快速路由发出 http 请求,该路由具有从数据库中获取的逻辑。 That logic should never live in the UI layer.该逻辑永远不应该存在于 UI 层中。

This route should then be called regardless of whether you are on the client or on the server - you don't need to do any code branching.无论您是在客户端还是在服务器上,都应该调用此路由 - 您不需要进行任何代码分支。

Make an API distinct from your next.js app.使 API 与您的 next.js 应用程序不同。 Think of the next app as a frontend client that happens to render pages on the server将下一个应用程序视为恰好在服务器上呈现页面的前端客户端

With time new solutions come around.随着时间的推移,新的解决方案出现了。
Nextjs has introduced a new method getServerSideProps primarily for such use cases Nextjs 引入了一种新方法getServerSideProps主要用于此类用例

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

For me, the quickest way I found is to get the data from __NEXT_DATA__对我来说,我找到的最快方法是从__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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM