简体   繁体   中英

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

I'm using Next.js, and I have a custom server using 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. However, getInitialProps() can also run on the client side (when the user initially requests a different page, then navigates to this one). 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.

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.

What's the best way to handle this?

getInitialProps() always receives the request and response as parameters which are only set on the server:

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

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. That logic should never live in the UI layer.

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. 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

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__

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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