20/02/2025, 09:07 cache – React
v19
API REFERENCE APIS
cache
React Server Components
cache is only for use with React Server Components.
cache lets you cache the result of a data fetch or computation.
const cachedFn = cache(fn);
Reference
cache(fn)
Usage
Cache an expensive computation
Share a snapshot of data
Preload data
Troubleshooting
My memoized function still runs even though I’ve called it with the
same arguments
Reference
cache(fn)
https://react.dev/reference/react/cache 1/13
20/02/2025, 09:07 cache – React
Call cache outside of any components to create a version of the function
with caching.
import {cache} from 'react';
import calculateMetrics from 'lib/metrics';
const getMetrics = cache(calculateMetrics);
function Chart({data}) {
const report = getMetrics(data);
// ...
}
When getMetrics is first called with data , getMetrics will call
calculateMetrics(data) and store the result in cache. If getMetrics is
called again with the same data , it will return the cached result instead of
calling calculateMetrics(data) again.
See more examples below.
Parameters
fn : The function you want to cache results for. fn can take any
arguments and return any value.
Returns
cache returns a cached version of fn with the same type signature. It does
not call fn in the process.
When calling cachedFn with given arguments, it first checks if a cached
result exists in the cache. If a cached result exists, it returns the result. If not,
it calls fn with the arguments, stores the result in the cache, and returns the
result. The only time fn is called is when there is a cache miss.
Note
https://react.dev/reference/react/cache 2/13
20/02/2025, 09:07 cache – React
The optimization of caching return values based on inputs is known
as memoization. We refer to the function returned from cache as a
memoized function.
Caveats
React will invalidate the cache for all memoized functions for each server
request.
Each call to cache creates a new function. This means that calling cache
with the same function multiple times will return different memoized
functions that do not share the same cache.
cachedFn will also cache errors. If fn throws an error for certain
arguments, it will be cached, and the same error is re-thrown when
cachedFn is called with those same arguments.
cache is for use in Server Components only.
Usage
Cache an expensive computation
Use cache to skip duplicate work.
import {cache} from 'react';
import calculateUserMetrics from 'lib/user';
const getUserMetrics = cache(calculateUserMetrics);
function Profile({user}) {
const metrics = getUserMetrics(user) ;
// ...
}
function TeamReport({users}) {
for (let user in users) {
https://react.dev/reference/react/cache 3/13
20/02/2025, 09:07 cache – React
const metrics = getUserMetrics(user) ;
// ...
}
// ...
}
If the same user object is rendered in both Profile and TeamReport , the
two components can share work and only call calculateUserMetrics once
for that user .
Assume Profile is rendered first. It will call getUserMetrics , and check if
there is a cached result. Since it is the first time getUserMetrics is called
with that user , there will be a cache miss. getUserMetrics will then call
calculateUserMetrics with that user and write the result to cache.
When TeamReport renders its list of users and reaches the same user
object, it will call getUserMetrics and read the result from cache.
Pitfall
Calling different memoized functions will read from different
caches.
To access the same cache, components must call the same
memoized function.
// Temperature.js
import {cache} from 'react';
import {calculateWeekReport} from './report';
export function Temperature({cityData}) {
// 🚩 Wrong: Calling `cache` in component creates new `getWeek
const getWeekReport = cache(calculateWeekReport) ;
const report = getWeekReport (cityData);
// ...
https://react.dev/reference/react/cache 4/13
20/02/2025, 09:07 cache – React
// Precipitation.js
import {cache} from 'react';
import {calculateWeekReport} from './report';
// 🚩 Wrong: `getWeekReport` is only accessible for `Precipitation
const getWeekReport = cache(calculateWeekReport) ;
export function Precipitation({cityData}) {
const report = getWeekReport (cityData);
// ...
}
In the above example, Precipitation and Temperature each call
cache to create a new memoized function with their own cache look-
up. If both components render for the same cityData , they will do
duplicate work to call calculateWeekReport .
In addition, Temperature creates a new memoized function each
time the component is rendered which doesn’t allow for any cache
sharing.
To maximize cache hits and reduce work, the two components
should call the same memoized function to access the same cache.
Instead, define the memoized function in a dedicated module that
can be import -ed across components.
// getWeekReport.js
import {cache} from 'react';
import {calculateWeekReport} from './report';
export default cache(calculateWeekReport) ;
// Temperature.js
https://react.dev/reference/react/cache 5/13
20/02/2025, 09:07 cache – React
import getWeekReport from './getWeekReport';
export default function Temperature({cityData}) {
const report = getWeekReport (cityData);
// ...
}
// Precipitation.js
import getWeekReport from './getWeekReport';
export default function Precipitation({cityData}) {
const report = getWeekReport (cityData);
// ...
}
Here, both components call the same memoized function exported
from ./getWeekReport.js to read and write to the same cache.
Share a snapshot of data
To share a snapshot of data between components, call cache with a data-
fetching function like fetch . When multiple components make the same
data fetch, only one request is made and the data returned is cached and
shared across components. All components refer to the same snapshot of
data across the server render.
import {cache} from 'react';
import {fetchTemperature} from './api.js';
const getTemperature = cache(async ( city ) => {
return await fetchTemperature(city) ;
});
async function AnimatedWeatherCard({city}) {
const temperature = await getTemperature ( city );
// ...
https://react.dev/reference/react/cache 6/13
20/02/2025, 09:07 cache – React
async function MinimalWeatherCard({city}) {
const temperature = await getTemperature ( city );
// ...
}
If AnimatedWeatherCard and MinimalWeatherCard both render for the same
city , they will receive the same snapshot of data from the memoized
function .
If AnimatedWeatherCard and MinimalWeatherCard supply different city
arguments to getTemperature , then fetchTemperature will be called twice
and each call site will receive different data.
The city acts as a cache key.
Note
Asynchronous rendering is only supported for Server Components.
async function AnimatedWeatherCard({city}) {
const temperature = await getTemperature(city);
// ...
}
Preload data
By caching a long-running data fetch, you can kick off asynchronous work
prior to rendering the component.
const getUser = cache(async (id) => {
https://react.dev/reference/react/cache 7/13
20/02/2025, 09:07 cache – React
return await db.user.query(id);
});
async function Profile({id}) {
const user = await getUser(id) ;
return (
<section>
<img src={user.profilePic} />
<h2>{user.name}</h2>
</section>
);
}
function Page({id}) {
// ✅ Good: start fetching the user data
getUser(id) ;
// ... some computational work
return (
<>
<Profile id={id} />
</>
);
}
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.
DEEP DIVE
Caching asynchronous work
https://react.dev/reference/react/cache 8/13
20/02/2025, 09:07 cache – React
Show Details
Pitfall
Calling a memoized function outside of a component will not use
the cache.
import {cache} from 'react';
const getUser = cache(async (userId) => {
return await db.user.query(userId);
});
// 🚩 Wrong: Calling memoized function outside of component will n
getUser('demo-id');
async function DemoProfile() {
// ✅ Good: `getUser` will memoize.
const user = await getUser('demo-id');
return <Profile user={user} />;
}
React only provides cache access to the memoized function in a
component. When calling getUser outside of a component, it will
still evaluate the function but not read or update the cache.
This is because cache access is provided through a context which is
only accessible from a component.
https://react.dev/reference/react/cache 9/13
20/02/2025, 09:07 cache – React
DEEP DIVE
When should I use cache , memo , or useMemo ?
Show Details
Troubleshooting
My memoized function still runs even though I’ve
called it with the same arguments
See prior mentioned pitfalls
Calling different memoized functions will read from different caches.
Calling a memoized function outside of a component will not use the
cache.
If none of the above apply, it may be a problem with how React checks if
something exists in cache.
If your arguments are not primitives (ex. objects, functions, arrays), ensure
you’re passing the same object reference.
When calling a memoized function, React will look up the input arguments to
see if a result is already cached. React will use shallow equality of the
arguments to determine if there is a cache hit.
import {cache} from 'react';
const calculateNorm = cache((vector) => {
// ...
});
https://react.dev/reference/react/cache 10/13
20/02/2025, 09:07 cache – React
function MapMarker(props) {
// 🚩 Wrong: props is an object that changes every render.
const length = calculateNorm(props);
// ...
}
function App() {
return (
<>
<MapMarker x={10} y={10} z={10} />
<MapMarker x={10} y={10} z={10} />
</>
);
}
In this case the two MapMarker s look like they’re doing the same work and
calling calculateNorm with the same value of {x: 10, y: 10, z:10} . Even
though the objects contain the same values, they are not the same object
reference as each component creates its own props object.
React will call Object.is on the input to verify if there is a cache hit.
import {cache} from 'react';
const calculateNorm = cache((x, y, z) => {
// ...
});
function MapMarker(props) {
// ✅ Good: Pass primitives to memoized function
const length = calculateNorm(props.x, props.y, props.z);
// ...
}
function App() {
return (
<>
<MapMarker x={10} y={10} z={10} />
<MapMarker x={10} y={10} z={10} />
</>
);
https://react.dev/reference/react/cache 11/13
20/02/2025, 09:07 cache – React
One way to address this could be to pass the vector dimensions to
calculateNorm . This works because the dimensions themselves are
primitives.
Another solution may be to pass the vector object itself as a prop to the
component. We’ll need to pass the same object to both component
instances.
import {cache} from 'react';
const calculateNorm = cache((vector) => {
// ...
});
function MapMarker(props) {
// ✅ Good: Pass the same `vector` object
const length = calculateNorm(props.vector);
// ...
}
function App() {
const vector = [10, 10, 10];
return (
<>
<MapMarker vector={vector} />
<MapMarker vector={vector} />
</>
);
}
PREVIOUS
act
NEXT
https://react.dev/reference/react/cache 12/13
20/02/2025, 09:07 cache – React
createContext
Copyright © Meta Platforms, Inc
uwu?
Learn React API Reference
Quick Start React APIs
Installation React DOM APIs
Describing the UI
Adding Interactivity
Managing State
Escape Hatches
Community More
Code of Conduct Blog
Meet the Team React Native
Docs Contributors Privacy
Acknowledgements Terms
https://react.dev/reference/react/cache 13/13