Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve data server side and save in context with Next.js

I would like to be able to retrieve data from an API, server-side, and load it into React context, in order to make it available to any component in my app. I have tried various things, but nothing seems to allow me to do exactly what I want. Some things I've tried include:

getServerSideProps - This allows me to retrieve the data, server-side, but only exists for Page components, so if I want this available on every page, and I don't know which page my user will land on, I'll need to add logic for this to every single page.

getInitialProps in _app.js - I can add this to the _app.js component, which will run server-side, and can make it available to all components via a context provider, but the problem is that it runs on every single page, even when navigating client-side. I would like to be able to call the API once and only once, and this doesn't seem to allow that.

getInitialProps in _document.js - I can add this to the _document.js component, which only runs on the server, which seems to address the problem of it being called for every page, but I cannot figure out how to store it in React context from there. In fact, I can't seem to figure out how to access this data anywhere. It looks like getInitialProps in _document.js is called after getInitialProps in _app.js, so I'm not sure if I can use the value I generate from getInitialProps in _document.js when I am in _app.js.

There are a number of ways I can make this work if I call the API on the client, but that won't work for my use case as it will cause a flash of content when the client updates with the data from the API.

Has anyone come up with a way of addressing this use case?

like image 463
BobSilverberg Avatar asked Feb 08 '21 17:02

BobSilverberg


People also ask

Can I use fetch in Nextjs?

Data fetching in Next. js allows you to render your content in different ways, depending on your application's use case. These include pre-rendering with Server-side Rendering or Static Generation, and updating or creating content at runtime with Incremental Static Regeneration.

Does Next JS render server-side?

Next. js has two forms of pre-rendering: Static Generation and Server-side Rendering.

Can I use fetch in getStaticProps?

Alternatively, if you are not using API routes to fetch data, then the fetch() API can be used directly in getStaticProps to fetch data.

What is difference between getStaticProps and getServerSideProps?

getStaticProps(): A method that tells the Next component to populate props and render into a static HTML page at build time. getServerSideProps(): A method that tells the Next component to populate the props and render into a static HTML page at run time.


Video Answer


2 Answers

In Next.js, there's no native function to a) retrieve data from an API, b) do it on the server, c) make it available on every page, and d) only query the API on the first page the user visits.

As you've found out, getInitialProps and getServerSideProps will run every time you visit that page.

However, we can get this to work.

If you need the data before the initial load

  1. Use getInitialProps in _app.js to retrieve data from the API
  2. Load the data into React context inside the _app.js file so it persists between pages
  3. When the browser gets the data, create a cookie.
  4. On a subsequent page load, in getInitialProps, check if there's a cookie. If so, don't retrieve the data.

There's a fairly popular library called nookies to help with cookies in a Next.js project.

If you can load the page then fetch the data

There is a performance cost to using getInitialProps in _app.js: you'll never be able to create a fully static page. That's because getInitialProps will have to run on every single page load.

If you can fetch the data after page load, add an API route. Then, in the context provider, use useEffect to fetch the data.

like image 163
Nick Avatar answered Oct 11 '22 12:10

Nick


Maybe Redux could be a solution for your issues. Context api tends to trigger unnecessary re rendering of the consumers.

like image 1
mitopalov Avatar answered Oct 11 '22 13:10

mitopalov