Next.js Discord

Discord Forum

Get data from DB at app initial loading, then access to it everywhere

Unanswered
Podenco Canario posted this in #help-forum
Open in Discord
Podenco CanarioOP
Hello,

I'm using NextJS 14.0 with Supabase
I have a bunch of tables I wanna use everywhere in my app client-side. But I struggle to find a right approach to use correctly the caching of NextJS (getting my data refreshed only every 1h is perfect) and using it everywhere without repeating myself.

Example :
- I have a table named "Ressource" that throw to me an array with a bunch of... ressource
- I have 3 components from 3 different pages
- All those 3 components needs the exact same data : the whole array that I get from my "Ressource" table

How do I achieve this without doing 3 times the requests, 3 times the code to my third-party lib ?

I've tried using Context and Zustand but I get the feel that it's kinda wrong to do it that way.

Is there a way to "Load everything I'll need at init", then "access it from everywhere in my app on client side with just a simple line" (like I would do with Zustand) ?

Sorry if it's kind of a beginner question, but I've tried so many things now, and I can't find a satisfying answer on how to handle that.

I've read all the doc on NextJS about data fetching, route handlers, cache but I didn't understand how to achieve this without getting data on every page, and then passing it to the client components as props, repeating endlessly myself.

TL;DR : I want to have something like Zustand but with data fetch from something really high (like layout.ts) because I know this data won't change anytime soon.

10 Replies

Just FYI, when you use fetch multiple times on the same request to the same resource, the requests are memoized. So in your example, if you fetched 3 times total for your 3 pages, you would technically only being fetching the first time. The other 2 times you would hit the cache

See more: https://nextjs.org/docs/app/building-your-application/caching#request-memoization

If you are not using fetch, you could also look into React cache for similar behaviour:
https://react.dev/reference/react/cache
Podenco CanarioOP
Hello @jason thx for your answer. As I said I've read already a lot about that.
My question is more about how to avoid repetition in my code and refactors those query as just one big way to redistribute it without props-drilling.
Just as Zustand answer many problems providing a global state.
I'm looking for a way to get a "global data".

Right now I'm using context, but I'm wondering if there's a better possibility than wrapping my whole app into a context (which I'm not very fan of)
@Ray maybe use react-query and fetch the initial data on server then pass it to ther query
Podenco CanarioOP
How would you pass this from server to client ?
@Podenco Canario How would you pass this from server to client ?
like this
// action
export async function fetchData() {
  return fetch("url").then(res => res.json())
}

export default async function Page() {
  const data = await fetchData()

  return <Client data={data} />
}

export function Client(data) {
  const {} = useQuery({queryKey: ['data'], queryFn: fetchData, placeholderData: data })

  ...
}
Podenco CanarioOP
Ok interesting, it does not prevent from props-drilling data in your case, right ? 🤔 or am I reading this wrong
I've read : https://tanstack.com/query/v4/docs/framework/react/guides/ssr#using-initialdata
And it says :
If you are calling useQuery in a component deeper down in the tree you need to pass the initialData down to that point
If you are calling useQuery with the same query in multiple locations, you need to pass initialData to all of them
Podenco CanarioOP
Nice, I'll dive a bit into it and try some things arounds.
From what I understand <Provider> act as my <ContextProvider> works right now, but revolving around queries instead of a "basic" Context Provider 🤔
Thx for the hints ! 👍