Next.js Discord

Discord Forum

Caching number/ session auth in a layout component

Answered
Hudsonian Godwit posted this in #help-forum
Open in Discord
Avatar
Hudsonian GodwitOP
NextJS14(App router), React18: I'm displaying a cached number in a layout for multiple pages. To fetch it I need to validate my session which is NOT possible in unstable_cache() since cookies are not accessible there. I could pass the session to the cache function, which in turn would mean that the validation triggers on every render of the layout. However I already perform session validation on a page level. So now I validate it twice on each render... Is there a way around this?
Answered by Alfonsus Ardani
like you would only need to cache() this part

  const session = await checkAuth()
  if (!session.isLoggedIn || session.pbAuth == null) throw new Error("Couldn't authenticate!")

  pb.authStore.save(session.pbAuth)


and the rest should go to unstable_cache
View full answer

22 Replies

Avatar
use the cache function from React
wrap your session validation logic in that and voila
only render once per request
Avatar
Hudsonian GodwitOP
I swear I tried that and it didn't work, but i'll try it again. So use cache() for both the auth check and the data fetching in the same function?
Avatar
yeah
Avatar
Hudsonian GodwitOP
Funnily enough I was already using it, I forgot:

export const getCachedKomCount = cache(async () => {
  console.log("Fetching KOM Count")
  const session = await checkAuth()
  if (!session.isLoggedIn || session.pbAuth == null) throw new Error("Couldn't authenticate!")

  pb.authStore.save(session.pbAuth)

  return pb.collection(Collections.KomTimeseries).getFirstListItem("", {
    sort: "-created",
  })
})
Avatar
then it should only be done once per request
wait
thats kinda wrong lol
Avatar
Hudsonian GodwitOP
layout:

const DashboardLayout = async ({ children }: { children: React.ReactNode }) => {
  const timeSeriesPromise = getCachedKomCount()
...

<Suspense fallback={<span>0</span>}>
                <TotalKomCount timeSeriesPromise={timeSeriesPromise} />
              
</Suspense>
Avatar
yeah thats kinda wrong
Avatar
Hudsonian GodwitOP
enlighten me
Avatar
but
Avatar
like you would only need to cache() this part

  const session = await checkAuth()
  if (!session.isLoggedIn || session.pbAuth == null) throw new Error("Couldn't authenticate!")

  pb.authStore.save(session.pbAuth)


and the rest should go to unstable_cache
Answer
Avatar
but its not that important, it should work
Avatar
Hudsonian GodwitOP
combiningboth approaches, I havn't tried yet
Avatar
not combining, separating
Avatar
Hudsonian GodwitOP
that's what I meant
using the approach as it is right now. It does not work I see a db request in the db logs for each render
running on localhost if that matters
Avatar
Hudsonian GodwitOP
using cache() for session and unstable_cache() for the data seem to work