DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Edited on

Cache your function computation in React Server Components

In this article, you will learn what a cache in React is and also analyse how it is used in nextjs-subscription-payments example.

Image description

Cache

Cache is only for use in React Server Components. React documentation suggests to cache a function that does data fetch or complex computation

These three below examples are provided in the React documentation about cache:

It is important that you read these usage examples and understand the common pitfalls to apply cache.

Read more about cache.

Cache usage in Nextjs-Subscription-Payments

In queries.ts in nextjs-subscription-payments, you will find the below code:

import { SupabaseClient } from '@supabase/supabase-js';
import { cache } from 'react';
export const getUser = cache(async (supabase: SupabaseClient) => {
 const {
 data: { user }
 } = await supabase.auth.getUser();
 return user;
});
Enter fullscreen mode Exit fullscreen mode

Notice the cache applied to the arrow function above. Where is this function called though? you will find this below code in app/page.tsx

import {
 getProducts,
 getSubscription,
 getUser
} from '@/utils/supabase/queries';

export default async function PricingPage() {
 const supabase = createClient();
 const [user, products, subscription] = await Promise.all([
 getUser(supabase),
 getProducts(supabase),
 getSubscription(supabase)
]);
Enter fullscreen mode Exit fullscreen mode

The usecase, Preload data applies here. I am going to quote what is provided in preload data usage example

When rendering Page, the component calls getUser but note that it doesn’t use the returned data.This early getUser call kicks off the asynchronous database query that occurs while Page is doing other computational work and rendering children.

When rendering Profile, we call getUser again. If the initial getUser call has already returned and cached the user data, when Profile asks and waits for this data, it can simply read from the cache without requiring another remote procedure call. If the initial data request hasn’t been completed, preloading data in this pattern reduces delay in data-fetching.

There is one more place/file where getUser is called. You will find the below code in app/account/page.tsx

import {
 getUserDetails,
 getSubscription,
 getUser
} from '@/utils/supabase/queries';
export default async function Account() {
 const supabase = createClient();
 const [user, userDetails, subscription] = await Promise.all([
 getUser(supabase),
 getUserDetails(supabase),
 getSubscription(supabase)
]);
Enter fullscreen mode Exit fullscreen mode

Both, app/page.tsx and app/account/page.tsx, are server components.

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on an interesting project. Send me an email at ramu.narasinga@gmail.com

My Github - https://github.com/ramu-narasinga
My website - https://ramunarasinga.com
My Youtube channel - https://www.youtube.com/@thinkthroo
Learning platform - https://thinkthroo.com
Codebase Architecture - https://app.thinkthroo.com/architecture
Best practices - https://app.thinkthroo.com/best-practices
Production-grade projects - https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/vercel/nextjs-subscription-payments/blob/main/utils/supabase/queries.ts#L4

  2. https://react.dev/reference/react/cache

  3. https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components

  4. https://github.com/vercel/nextjs-subscription-payments/blob/1623fb9d1820637ba55cd0af1012bb85237118b8/app/page.tsx#L12

  5. https://github.com/vercel/nextjs-subscription-payments/blob/1623fb9d1820637ba55cd0af1012bb85237118b8/app/account/page.tsx#L15

Top comments (0)