useMutationとは?
React Queryでデータを登録・編集・削除したりする場合に使います。AXIOSなどのHTTPライブラリの代替プラスキャッシュ機能を持っている感じです。
動きとしては、APIでバックエンドのデータを更新した上でそれをキャッシュしているというようなイメージです。(キャッシュの上書きなどはReact-QueryのuseMutateが自動でやってくれるのではなく、APIリクエストが成功した後のonSuccessというフックを使ってその中でqueryClient.setQueryDataで明示的に開発者がキャッシュ内容を更新します。)
登録処理のサンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import axios from 'axios' import { useAppDispatch } from '../app/hooks' import { resetEditedTask } from '../slices/todoSlice' import { useQueryClient, useMutation } from '@tanstack/react-query' export const useMutateTask = () => { const dispatch = useAppDispatch() const queryClient = useQueryClient() const createTaskMutation = useMutation( (POSTデータ: データ型) => axios.post<データ型>("APIのURL", POSTデータ), { onSuccess: (res) => { const 既存データ = queryClient.getQueryData<データ型[]>(['キー']) if (既存データ) { queryClient.setQueryData<データ型[]>(['キー'], [ ...既存データ, res.data, ]) } dispatch(resetEditedTask()) }, } ) return { createTaskMutation } } |
onSuccess
APIのリクエストが成功した場合の後処理を記述することが可能です。登録処理であれば、まずは既存データをgetQueryDataにより取得して登録完了したデータを追加します。
queryClient.setQueryData
新しいデータでキャッシュの内容を上書きすることができます。キャッシュの上書きなどはuseMutateが自動でやってくれるのではなく、APIリクエストが成功した後のonSuccessというフックを使って実施します。
呼び出すコンポーネント側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import { VFC, FormEvent } from 'react' import { useAppSelector, useAppDispatch } from '../app/hooks' import { setEditedTask, selectTask } from '../slices/todoSlice' import { useMutateTask } from '../hooks/useMutateTask' const TaskEdit: VFC = () => { const editedTask = useAppSelector(selectTask) const dispatch = useAppDispatch() const { createTaskMutation } = useMutateTask() const submitHandler = (e: FormEvent<HTMLFormElement>) => { e.preventDefault() createTaskMutation.mutate(editedTask) } if (createTaskMutation.isLoading) { return <span>Creating...</span> } return ( <div> <form onSubmit={submitHandler}> <input type="text" onChange={(e) => dispatch(setEditedTask({ ...editedTask, title: e.target.value })) } value={editedTask.title} /> <button>'Create'</button> </form> </div> ) } export default TaskEdit |
useMutationの関数.mutate(引数)
用意したMutationの関数を実行できます。
useMutationの関数.isLoading
通信ステータスなども上記の記述で取得できます。
レンダリングされるタイミング
useMutationを呼び出すタイミングで一度レンダリングされます。また、useMutationでAPI呼び出しが終わった後にももう一度レンダリングされます。useMutationを使う場合は2度レンダリングされることになります。
この記事へのコメントはありません。