nexusCache
nexusCache
is a utility for advanced use cases that require direct, synchronous access to the client-side cache.
Import
import { nexusCache } from "next-nexus/client";
Core Concepts
Direct Cache Access
nexusCache
returns a handle that allows you to synchronously read from and write to the cache entry for a specific GET
definition.
When to Use
It is primarily intended for implementing complex patterns like optimistic updates, where you want to update the UI instantly before the server has confirmed a change. For most other use cases, such as refetching data after a mutation, using revalidateClientTags
is the recommended approach as it is less error-prone.
Limitations
- GET-only:
nexusCache
only supportsGET
definitions. Calling it with a non-GET definition will throw an error. - Advanced Use Only: Manual cache writes are powerful but can easily lead to inconsistencies between the client UI and the server’s state. Prefer tag-based revalidation wherever possible.
API
Given const cache = nexusCache(definition)
, the following methods are available:
get(): T | undefined
: Returns the current cached data, orundefined
if none exists.set(updater: (old: T | undefined) => T): void
: Updates the cache entry. Theupdater
function receives the previous state and should return the new state.remove(): void
: Removes the entry from the cache.invalidate(): void
: Marks the cache entry as stale, which will trigger a refetch on the nextuseNexusQuery
render.isStale(): boolean
: Returnstrue
if the entry is marked as stale.subscribe(fn: (data: T | undefined) => void): () => void
: Subscribes to changes in the cache entry. Returns anunsubscribe
function.
Example: Optimistic Updates
In this example, when a new todo is being created, we use onStart
in useNexusMutation
to immediately add a temporary item to the cached list. If the mutation fails, we roll back the change in onError
.
"use client";
import {
useNexusMutation,
nexusCache,
revalidateClientTags,
} from "next-nexus/client";
import { todosDefinition } from "@/definitions";
export function AddTodo() {
const listCache = nexusCache(todosDefinition.list);
const { mutate, isPending } = useNexusMutation(todosDefinition.create, {
onStart: (input) => {
// Immediately add a temporary item to the list
listCache.set((prev) =>
prev ? [{ id: "__temp__", title: input.title }, ...prev] : prev
);
},
onSuccess: () => {
// The successful mutation should trigger a revalidation to get the real data
revalidateClientTags(["todos"]);
},
onError: () => {
// If the mutation fails, invalidate the cache to roll back the optimistic update
listCache.invalidate();
},
});
return (
<button onClick={() => mutate({ title: "New Todo" })} disabled={isPending}>
Add
</button>
);
}
See also