この記事を作成した目的
React Queryで理解しにくかったところをまとめる
従来のuseStateで状態管理する場合
状態管理・ローディング状態・エラー処理・再取得は手動で管理していました。
以下は学習記録のデータを取得するコードです。
const [studyRecords, setStudyRecords] = useState<StudyRecord[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchStudyRecords = async () => {
setLoading(true);
setError(null);
try {
const response = await api.get("http://localhost:3000/api/v1/study_records");
setStudyRecords(response.data.data);
} catch (error) {
console.log("詳細なエラー情報:", error);
setError("データの取得に失敗しました。");
} finally {
setLoading(false);
}
}
useEffect(() => {
fetchStudyRecords();
}, []);
React Queryの場合
React Queryでは上記のコードを以下のように書き直すことができます。
useQueryメソッドを使ってAPIからデータをフェッチしてQueryClientにキャッシュしています。
引数は2つあり、1つ目がkey、2つ目が関数です。
このkeyを使ってキャッシュしたデータを取得・更新・破棄・再取得などを行なっています。
2つ目の関数は、APIにリクエストを投げて受け取ったレスポンスをreturnするような非同期処理を行う関数です。
const { data: studyRecords = [], isLoading: loading, error } = useQuery({
queryKey: ['studyRecords'],
queryFn: async () => {
const response = await api.get('/study_records');
return response.data.data;
}
});
data: studyRecordsはdataというプロパティを取り出し、それをstudyRecordsという変数名にリネームしています。
React QueryではuseMutationでデータを変更することも出来る
queryClient.invalidateQueriesで学習記録一覧のキャッシュを無効化 → 最新データを再取得する
const queryClient = useQueryClient();
const addMutation = useMutation({
mutationFn: async (studyFormData: StudyFormData) => {
const response = await api.post('/study_records', {
study_record: {
title: studyFormData.title,
time: Number(studyFormData.time)
}
});
return response.data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['studyRecords'] })
reset();
}
})
useStateとReact Queryの違いを表でまとめると以下のようになります。
| 項目 | useState | React Query |
|---|---|---|
| 状態管理 | 手動 | 自動 |
| ローディング状態 | 手動で管理 | 自動で提供 |
| エラー処理 | 手動で管理 | 自動で提供 |
| キャッシュ | なし | 自動でキャッシュ |
| 再取得 | 手動で呼び出し | 自動で再取得 |
useQueryで取得したデータの使い方
React Queryで取得したデータは基本的に配列で、mapメソッドで以下のように使用することが多い。dataをリネームした変数(ここではstudyRecords)はuseStateの第一引数と全く同じように使える。
return (
<div>
{studyRecords.map(record => (
<div key={record.id}>{record.title}</div>
))}
</div>
);
参考
React Queryはデータフェッチライブラリではない。非同期の状態管理ライブラリだ。
React Queryこれだけは抑えておくべきメソッド3つ