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?
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.
Next. js has two forms of pre-rendering: Static Generation and Server-side Rendering.
Alternatively, if you are not using API routes to fetch data, then the fetch() API can be used directly in getStaticProps to fetch data.
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.
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.
getInitialProps
in _app.js
to retrieve data from the API_app.js
file so it persists between pagesgetInitialProps
, 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.
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.
Maybe Redux could be a solution for your issues. Context api tends to trigger unnecessary re rendering of the consumers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With