Hook Builders
Hook builders initialize useQuery
, useImmutate
, useInfinite
, and useMutate
.
Each builder function accepts an instance of a fetch client and a prefix unique to that client.
TIP
Prefixes ensure that swr
will avoid caching requests from different APIs when requests happen to match (e.g. GET /health
for "API A" and GET /health
for "API B").
import createClient from "openapi-fetch";
import { isMatch } from "lodash-es";
import {
createQueryHook,
createImmutableHook,
createInfiniteHook,
createMutateHook,
} from "swr-openapi";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
const client = createClient<paths>(/* ... */);
const prefix = "my-api";
export const useQuery = createQueryHook(client, prefix);
export const useImmutable = createImmutableHook(client, prefix);
export const useInfinite = createInfiniteHook(client, prefix);
export const useMutate = createMutateHook(
client,
prefix,
isMatch, // Or any comparision function
);
API
Parameters
Each builder hook accepts the same initial parameters:
client
: A fetch client.prefix
: A prefix unique to the fetch client.
createMutateHook
also accepts a third parameter:
compare
: A function to compare fetch options).
Returns
createQueryHook
→useQuery
createImmutableHook
→useImmutable
createInfiniteHook
→useInfinite
createMutateHook
→useMutate
compare
When calling createMutateHook
, a function must be provided with the following contract:
type Compare = (init: any, partialInit: object) => boolean;
This function is used to determine whether or not a cached request should be updated when mutate
is called with fetch options.
My personal recommendation is to use lodash's isMatch
:
Performs a partial deep comparison between object and source to determine if object contains equivalent property values.
const useMutate = createMutateHook(client, "<unique-key>", isMatch);
const mutate = useMutate();
await mutate([
"/path",
{
params: {
query: {
version: "beta",
},
},
},
]);
// ✅ Would be updated
useQuery("/path", {
params: {
query: {
version: "beta",
},
},
});
// ✅ Would be updated
useQuery("/path", {
params: {
query: {
version: "beta",
other: true,
example: [1, 2, 3],
},
},
});
// ❌ Would not be updated
useQuery("/path", {
params: {
query: {},
},
});
// ❌ Would not be updated
useQuery("/path");
// ❌ Would not be updated
useQuery("/path", {
params: {
query: {
version: "alpha",
},
},
});
// ❌ Would not be updated
useQuery("/path", {
params: {
query: {
different: "items",
},
},
});