React Query
React Query を使い始めるにあたり、とりあえず知っておきたいことのメモ。
React Queryとは
- データのフェッチ、キャッシュ、同期、更新を簡単に行うことができるライブラリ。
- 現在はTanStack Queryという名前に変わっている。
- ReactQueryはversion3まであり、version4からはTanStack Queryという名前に変わった。
- TanStack QueryはReact以外にSolid,Vue,Svelteに対応している
Queries
- データの取得(GETリクエスト)をするとき、useQueryフックを使う
- 1つのエンドポイントに対して1つのqueryKeyを定義することで、データのキャッシュが正しく行われるようにする
- オプション
- enabled
- 自動的にクエリを実行させたくない場合にfalseを指定する
- cacheTime
- データのキャッシュが有効な時間
- デフォルトでは300000ms(5分)
- staleTime
- キャッシュが古くなったと判断するまでの時間
- デフォルトでは0ms
- cacheTime, staleTimeがデフォルト値であれば、ページ表示時にキャッシュデータを返したあと、キャッシュが古くなったと判断してフェッチが実行され、データが更新されていればキャッシュが書き換えられる。
- enabled
// https://tanstack.com/query/v4/docs/overview より抜粋 const { isLoading, error, data } = useQuery({ queryKey: ['repoData'], queryFn: () => fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => res.json() ) }) if (isLoading) return 'Loading...' if (error) return 'An error has occurred: ' + error.message return ( <div> <h1>{data.name}</h1> <p>{data.description}</p> <strong>👀 {data.subscribers_count}</strong>{' '} <strong>✨ {data.stargazers_count}</strong>{' '} <strong>🍴 {data.forks_count}</strong> </div> )
Prefetching
- データのフェッチ前にキャッシュデータを作っておき、フェッチ中にキャッシュデータを表示できるようにする
// https://tanstack.com/query/v4/docs/guides/prefetching より抜粋 const prefetchTodos = async () => { // The results of this query will be cached like a normal query await queryClient.prefetchQuery({ queryKey: ['todos'], queryFn: fetchTodos, }) }
Mutations
- データの更新(POST/PATCH/DELETEリクエスト)をするとき、useMutationフックを使う
- オプション
- onMutate
- mutationが実行される前に呼び出される。Optimistic update を行うために使用する(先に画面上のデータを新しいデータで更新しておいて、更新処理を実行するときに使用)
- onSuccess
- 更新処理が成功したときに実行される。データキャッシュをクリアしたいときはここにinvalidateQueriesを記述。
- onError
- 更新処理に失敗したときに実行される
- onSettled
- 更新処理が成功しても失敗しても実行される。onSuccessまたはonErrorのあとに実行される。
- onMutate
// https://tanstack.com/query/v4/docs/quick-start より抜粋 const mutation = useMutation({ mutationFn: postTodo, // ここには () => axios.post(...) などのAPI実行を記述 onSuccess: () => { // Invalidate and refetch queryClient.invalidateQueries({ queryKey: ['todos'] }) }, }) : <button onClick={() => { mutation.mutate({ id: Date.now(), title: 'Do Laundry', }) }} >
データキャッシュをクリアする
- mutationを実行したあともデータキャッシュが残っているので画面上の表示がされない。このためonSuccessでqueryClient.invalidateQueries()を実行することで、指定したキーに対応するデータキャッシュをクリアする。