😸

React Queryのkey管理について

2021/04/12に公開

また React Query ネタになってしまった笑

問題提起

  • key の間違いが起こる

mutate の後に例えば accounts を再取得する場合 invalidateQueries('accounts') とすると accounts に対して更新がかかる。
mutate > 再取得という流れを考えるとかなり簡単に簡潔にコードを書くことができる。
が、ここで渡す key が string なので、key の間違いが起きてしまうという問題が起きてしまったり、目当ての key を検索などして探さなければならなくってしまう。

元の実装者が自分でなかったり、仮に前に実装したのが自分だとしても 3 日もすれば忘れてしまう。

やってみたこと

1 定数で key を管理する

QUERY_KEYS として定数化した。さらに型を定義しておく。

export const QUERY_KEYS = ["users", "post", "comments"] as const;

type Unpacked<T> = T extends { [K in keyof T]: infer U } ? U : never;
export type QueryKeysTypes = Unpacked<typeof QUERY_KEYS>;

2 カスタム queryClient

React Query の queryClient を Wrapper してカスタムする。queryClient 自体は他にも色々メソッドがあるが、今回は省略している。必要なものを return する感じで。
第一引数として key  を渡す。そこで先程の QueryKeysTypes で型ガードしておく。

export function useQueryClientWrapper(): {
  invalidateQueries: (k: QueryKeysTypes, deps?: QueryKey) => void;
} {
  const queryClient = useQueryClient();
  const invalidateQueries = useCallback(
    (key, deps) => {
      const k = Array.isArray(deps) ? [key, ...deps] : [key];
      queryClient.invalidateQueries(k);
    },
    [queryClient]
  );
  return { invalidateQueries };
}

3 useQueryWrapper にも同様に型定義しておく

以前書いた記事の useQueryWrapper  の queryKey に対して QueryKeysTypes を適用する。

https://zenn.dev/brachio_takumi/articles/20210226-react-query

type Props<T> = {
  queryKey?: QueryKeysTypes;
  deps?: QueryKey;
  options?: UseQueryOptions;
  req: () => Promise<AxiosResponse<T>>;
};

export const useQueryWrapper = <T>({
  queryKey,
  deps = [],
  options,
  req,
}: Props<T>): UseQueryResult<T> => {
  const k = Array.isArray(deps) ? [queryKey, ...deps] : [queryKey];
  const result = useQuery(
    k,
    async () => {
      try {
        const res = await req();
        return res.data;
      } catch (e) {
        // ここでトースト出したり
        throw e.error;
      }
    },
    options
  ) as UseQueryResult<T>;

  return result;
};

まとめ

これで型安全にできるし、エディターでサジェストされるようになる。

image

以下のようにエンドポイントごとの Query を作る際もサジェストされるようになっている。

なお、エンドポイントごとの Query については以前の記事をみていただけると!!
https://zenn.dev/brachio_takumi/articles/20210226-react-query

image

Discussion