Skip to content

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").

ts
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

compare

When calling createMutateHook, a function must be provided with the following contract:

ts
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.

ts
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",
    },
  },
});