Next.js Discord

Discord Forum

Memoization of fetch function not working

Unanswered
Magnificent Hummingbird posted this in #help-forum
Open in Discord
Magnificent HummingbirdOP
I have a function like this:
import { cookies } from 'next/headers';

export async function getUser() {
  const resp = await fetch(
    `http://localhost:8000/api/v3/users/me`,
    { headers: [['Cookie', cookies().toString()]] }
  );
  return await resp.json();
}

And use it in a component like so:
import { getUser } from '../../api/get-user';

export async function User() {
  const user = await getUser();
  return (
    <>
      <div>
        {user.name} &mdash; {user.email}
      </div>
    </>
  );
}

However, when I include that component three times in my layout, I see on the server that the endpoint gets called three times. I even tried removing the cookies header but it still gets called three times.

I know I can wrap it in the cache function from React , but the docs say that fetch is supposed to memoize automatically.

I'm using next 14.0.3

6 Replies

Toyger
next is completely fine here, cache will not help either, it have it's own caveats.
and logic is correct here, you have component that request data, it was rendered 3 times, so fetch will always run 3 times, and actually even on each re-render it will again run additional queries.
So what you need here is some single source of truth like context api or store(redux/jotai/mobx/...) where you will cache result yourself and will check your cache before request.
Also as another solutioon you can use tanstack-query for better implementation of requests with built-in cache exactly as you expected.
Siberian Flycatcher
I see on the server that the endpoint gets called three times
How do you debug this?
Magnificent HummingbirdOP
I have a separate django API and I see the logs
horus this is all happening in server components. I was refering to this behavior where it says this call should only happen once if done on server components: https://nextjs.org/docs/app/building-your-application/caching#request-memoization
also if it still be presented try to set fixed revalidate
fetch('https://...', { next: { revalidate: 3600 } })

for example 100ms should be more than enough.