Why `unstable_cache` don't cache same request made multiple time in the same start time ?
Unanswered
California pilchard posted this in #help-forum
California pilchardOP
Okay Im just learning how to properly cache in NextJS. I could use
But I dont know why, if I do the same request multiple time from
Am I missing something ?
"use cache"
but still unstable. SO my only solution is unstable_cache
, so I have this testing function :export const getTest = async () => {
return await unstable_cache(
async () => {
console.log('hello from getTest');
...
return data;
},
['test'],
{ revalidate: 10 } // 10sec for testing
)();
};
But I dont know why, if I do the same request multiple time from
layout.tsx
and page.tsx
(children), that call multiple time my function without being cached :MOVIE LAYOUT RENDERING
LANG LAYOUT RENDERING
hell from getTest # from layout.tsx
hell from getTest # from page.tsx
hell from getTest # from page.tsx (generateMetadata)
Am I missing something ?
14 Replies
@California pilchard Okay Im just learning how to properly cache in NextJS. I could use `"use cache"` but still unstable. SO my only solution is `unstable_cache`, so I have this testing function :
tsx
export const getTest = async () => {
return await unstable_cache(
async () => {
console.log('hello from getTest');
...
return data;
},
['test'],
{ revalidate: 10 } // 10sec for testing
)();
};
But I dont know why, if I do the same request multiple time from `layout.tsx` and `page.tsx` (children), that call multiple time my function without being cached :
sh
MOVIE LAYOUT RENDERING
LANG LAYOUT RENDERING
hell from getTest # from layout.tsx
hell from getTest # from page.tsx
hell from getTest # from page.tsx (generateMetadata)
Am I missing something ?
unstable_cache caches across request but does not dedupes within the same request (don't ask me why)
hence, just use it in combination with
hence, just use it in combination with
React.cache
and you are set@joulev unstable_cache caches across request but does not dedupes within the same request (don't ask me why)
hence, just use it in combination with `React.cache` and you are set
California pilchardOP
Do u know where I can find an example of combination of
unstable_cache
and cache
from react ? Because Ive test some stuff but isnt working... Btw use cache
work really well :hello from getTest
Cache hello from getTest
Cache hello from getTest
@California pilchard Do u know where I can find an example of combination of `unstable_cache` and `cache` from react ? Because Ive test some stuff but isnt working... Btw `use cache` work really well :
sh
hello from getTest
Cache hello from getTest
Cache hello from getTest
just wrap the function inside
cache
export const getTest = cache(() => {
return unstable_cache(
async () => {
console.log('hello from getTest');
...
return data;
},
['test'],
{ revalidate: 10 } // 10sec for testing
)();
});
Btw use cache work really well :no comment from me, i have never used use cache
@joulev just wrap the function inside `cache`
tsx
export const getTest = cache(() => {
return unstable_cache(
async () => {
console.log('hello from getTest');
...
return data;
},
['test'],
{ revalidate: 10 } // 10sec for testing
)();
});
> Btw use cache work really well :
no comment from me, i have never used use cache
California pilchardOP
I dont understand why in my case isnt working, I do the same thing :
With :
======Fetching movie with media key: [ 'fr-FR', 'movie', '1087192' ]
======Fetching movie with media key: [ 'fr-FR', 'movie', '1087192' ]
======Fetching movie with media key: [ 'fr-FR', 'movie', '1087192' ]
======Fetched movie with id: 1087192 in 588.1146249999874 ms
======Fetched movie with id: 1087192 in 587.7401250000112 ms
======Fetched movie with id: 1087192 in 572.4265410000226 ms
With :
export const getMovie = cache(({
locale,
id,
} : {
locale: string;
id: number;
}) => {
return unstable_cache(
async () => {
const t0 = performance.now();
console.log('======Fetching movie with media key:', mediaKeys.detail({ locale: locale, id: id, type: 'movie' }));
const supabase = await createClient(locale);
const { data: film, error } = await supabase
.from('media_movie')
.select(`*`)
.match({
'id': id,
})
.returns<MediaMovie[]>()
.maybeSingle();
const t1 = performance.now();
console.log(`======Fetched movie with id: ${id} in ${t1 - t0} ms`);
if (error) throw error;
return film;
},
['test'],
{
revalidate: MEDIA_REVALIDATE_TIME,
tags: ['tmdb']
}
)();
});
Its called 3 times (
layout
, page
and generateMetadata
) but after its well cached but the first time is broken idkhmm looks strange, sorry idk either
@joulev hmm looks strange, sorry idk either
California pilchardOP
Wait Ive test something :
WHen the function doesnt have params its well cached, but with this :
isnt cached well
const getTest = cache(
async () => {
console.log('getTest called');
await new Promise((resolve) => setTimeout(resolve, 1000));
return 'Test data';
},
{ tags: [`settings`], revalidate: 10 },
);
WHen the function doesnt have params its well cached, but with this :
const getTest = cache(
async ({ locale, id }: { locale: string; id: number }) => {
console.log('getTest called');
await new Promise((resolve) => setTimeout(resolve, 1000));
return 'Test data';
},
{ tags: [`settings`], revalidate: 10 },
);
isnt cached well
waiiiiiiiiit I think its working
If I do :
instead of :
export const getMovie = cache(
async (locale: string, id: number) => {
instead of :
export const getMovie = cache(
async ({ locale, id } : { locale: string; id: number}) => {
California pilchardOP
SO I guess its
cache()
from react
which isnt able to cache using object in params ?no idea man
methinks it has something to do with
objects cannot be compared with
===
objects cannot be compared with
===
but string
and number
canCalifornia pilchardOP
Okay I found why (probably) (from https://github.com/facebook/react/issues/31390) :
the objet isnt in the same instance when we call
the objet isnt in the same instance when we call
getMovie(object)
so the cache think its a different oneAnd also here : https://react.dev/reference/react/cache#troubleshooting