Next.js Discord

Discord Forum

How do we cache in NextJS ?

Unanswered
California pilchard posted this in #help-forum
Open in Discord
California pilchardOP
I have a layout.tsx and a page.tsx (with generateMetadata and a component) that call the exact same request (with supabase) :
export const getMovie = async ({
    locale,
    id,
} : {
    locale: string;
    id: number;
}) => {
    return await cache(
        async () => {
            console.log('Fetching movie with id:', id, 'for locale:', locale);
            ...
            return film;
        },
        mediaKeys.detail({ locale: locale, id: id, type: 'movie' }),
        {
            revalidate: MEDIA_REVALIDATE_TIME,
            tags: ['tmdb']
        }
    )();
};

But here my function console.log 9 time ahah. But once Ive see the movie, there is no console log anymore (so its cached) :

7 Replies

California pilchardOP
TO see where come from the request Ive add :
export const getMovie = async ({
    locale,
    id,
    callFrom,
} : {
    locale: string;
    id: number;
    callFrom: string;
}) => {
    return await cache(
        async () => {
            console.log('Fetching movie with id:', id, 'called from:', callFrom);

SO there is the result :
Fetching movie with id: 878608 called from: movie layout
Fetching movie with id: 878608 called from: movie page
Fetching movie with id: 878608 called from: movie generateMetadata
Fetched movie with id: 878608 in 527.4995000000054 ms, called from: movie layout
Fetched movie with id: 878608 in 524.7954579999932 ms, called from: movie page
Fetched movie with id: 878608 in 524.2085000000079 ms, called from: movie generateMetadata
California pilchardOP
So I guess isnt cached because every request are made in the same time before being cached
That weird because layout should render children without getting response from request... :
export default async function MovieLayout(
    props: {
        children: React.ReactNode;
        params: Promise<{
          lang: string;
          film_id: string;
        }>;
    }
) {
    const params = await props.params;
    const {
        children
    } = props;
    const { id: movieId } = getIdFromSlug(params.film_id);
    const movie = await getMovie({
      id: movieId,
      locale: params.lang,
      callFrom: 'movie layout',
    });
    if (!movie) notFound();
    return (children)
};
California pilchardOP
ALso why page.tsx is calling my request function before the layout.tsx finished
@California pilchard ALso why `page.tsx` is calling my request function before the `layout.tsx` finished
to answer this specific question (not the question in this post), page.tsx and layout.tsx are independent and hence executed independently in parallel
@joulev to answer this _specific_ question (not the question in this post), `page.tsx` and `layout.tsx` are independent and hence executed independently in parallel
California pilchardOP
Yes I didnt know children page.tsx was rendered in parallel of the layout.tsx. So if we are a layout.tsx like :
export default const layout = () => {
  const someValue = true;
  if (someValue) return null;
  return (children)
}

that means page.tsx gonna be loaded (and maybe make network request) even if the layout wont gonna render it ?