Why React cache() dedupes server reads
React cache() memoizes a function for one server request. That is why a layout and a page can both call getPostBySlug without hitting the disk twice.
· 1 min read · Code
In the App Router, a layout and a page can both need the same post. If each one reads the file itself, you pay the fs cost twice on one request. cache() from react is the per-request memo for that.
What it memoizes
cache(fn) returns a new function. For a given set of arguments, the first call runs fn. Later calls in the same server request return the stored result. A new request starts empty.
import { cache } from "react";
import { loadAllPosts } from "./load";
export const getAllPosts = cache(() => {
return loadAllPosts().filter((post) => post.status === "published");
});getAllPosts() in generateStaticParams and getAllPosts() in the page component share one array while that render is running.
What it is not
It is not a cross-request cache. It does not replace unstable_cache, the Data Cache, or a CDN. It does not survive to the next visitor.
It also does not deep-compare objects. Arguments are compared with Object.is. Pass a slug string, not a new options object on every call.
When to wrap
Wrap the function that is expensive and called from more than one Server Component: loaders, getPostBySlug, getPostsByTopic. Leave leaf formatters alone.
If two files export two separately wrapped copies of the same function, they do not share a cache. Export one wrapped function and import it.
Sources
Comments
Comments are off until Giscus is configured.