Caching and de-duplication
Caching and de-duplication in the Data fetching guide.
Be clear about what is and is not cached:
- There is no shared client cache for resources. Two components that each call
useResourcewith the same fetcher make two requests. Share one resource instead: create it in a parent (or in a context provider) and pass it down. A resource is a plain accessor, so passingprops.useror putting it in context shares the request, the state and every refetch. - Router loaders do have a cache keyed by route id, params and loader deps, with
staleTime, preloading, shared in-flight loads andinvalidate. See Caching and invalidation. - On the server, the renderer provides a per-render resource cache keyed by the resource
key, which is how values travel from the server tohydratewithout a second request. See SSR, hydration and streaming. Give a resource akeyoption for that; it is unrelated to client-side caching.
src/shared.tsxtsx
import { type Resource, useResource } from "@shadow-js/core";
export const calls = { fetches: 0 };
function load(): Promise<string> {
calls.fetches += 1;
return Promise.resolve("Ada");
}
function Greeting() {
const user = useResource(load);
return <span>{user.latest}</span>;
}
function GreetingFromParent(props: { user: Resource<string> }) {
return <span>{props.user.latest}</span>;
}
export function Separate() {
return (
<p>
<Greeting />
<Greeting />
</p>
);
}
export function Shared() {
const user = useResource(load);
return (
<p>
<GreetingFromParent user={user} />
<GreetingFromParent user={user} />
</p>
);
}