React Queryのkey管理を簡単に良い感じに行う
概要
react-queryを使っていてqueryKeyの管理をどうしようかと思い、公式のドキュメントでも紹介されていたlukemorales/query-key-factory を使用してみたら使い勝手が良かったので記事を書きました。
なぜReact Queryを使う上でqueryKeyの管理が重要になるか+ライブラリを使用せずqueryKeyを上手に管理する方法は下記の記事たちがとても参考になりました。
query-key-factoryの概要
Focus on writing and invalidating queries without the hassle of remembering how you've set up a key for a specific query! This lib will take care of the rest.
プロジェクトのREADMEの一番上に書かれている内容ですが、簡単な設定で型安全で自動保管付きのqueryKey管理を行うライブラリです。
プロジェクト構成
実際のプロジェクトではbulletproof-reactの構成を参考にsrc配下で機能ベースでディレクトリ分けを行なっており、下記のように各機能ベースでqueryKeyの管理をしています。
プロジェクト内でqueryKeyを設定するのは各queries.ts
内のみで行い、useQueryでのqueryKeyの指定やcacheのコントロール等queryKeyが使用される全ての箇所でここで定義したqueryKeyのみを使用します。
src/
- features/
- todos/
- queries.ts
- comments/
- queries.ts
機能ごとのQuery管理
各queriesファイル内で、下記のようにライブラリから提供されているcreateQueryKeys
を使用して、設定したいkeyごとにqueryKey
とqueryFn
(ここで設定しなくても良い)を記載します。
import { createQueryKeys, inferQueryKeys } from "@lukemorales/query-key-factory"
import { api } from 'features/todos/api'
export const todoQueries = createQueryKeys('todos', {
detail: (id: number) => ({
queryKey: [id],
queryFn: () => api.getTodoDetail(id)
}),
list: (filters: TodoFilters) => ({
queryKey: [{ filters }],
queryFn: () => api.getTodos({ filters }),
}),
});
export type TodoQueries = inferQueryKeys<typeof todoQueries>
あとは上記で定義したqueryKeyを必要な箇所で使用するだけです。
import { useQuery } from '@tanstack/react-query'
import { todoQueries } from 'features/todos/queries'
export const useTodoList= (filters: TodoFilters) => {
const { data, isLoading, error } = useQuery({
...todoQueries.all(filters),
}
})
return { data, isLoading, error }
}
感想
文字列だけでqueryKeyを管理するのと比べると、まとめて管理ができ、型安全・自動補完が効いてくれて開発がやりやすくなった気がしてます。
Discussion