サンプルを例に、React Queryの使い方を解説します。
入門レベルですが、参考になればと思います。
今回作成するサンプル
React Queryとaxiosを使って、GETとPOSTのHTTP通信を行うサンプルを作成しました。
- GET:取得したリストのデータを表示
- POST:ボタンクリックでレスポンスをアラートに表示
このサンプルを例に、React Queryの導入から使い方まで説明します。
まずは導入
1. プロジェクト作成
npx create-react-app <プロジェクト名> --template typescript
プロジェクトは、React + TypeScriptで作成します。
2. React Queryをインストール
$ npm i react-query
# または
$ yarn add react-query
npmまたはyarnでreact-queryをインストールします。
3. axiosをインストール
$ npm i axios
# または
$ yarn add axios
今回は、HTTP通信にはaxiosを使いますので、こちらもインストールします。
React Queryの使い方
下のコードを例に、React Queryの使い方を解説します。
APIには、JSONのデモデータを返してくれるJSONPlaceholderを使用しています。
import React from 'react';
import axios from 'axios';
import './App.css';
import {
QueryClient,
QueryClientProvider,
useMutation,
useQuery,
useQueryClient,
} from 'react-query';
type Post = {
id: number;
title: string;
body: string;
userId: number;
};
const Posts = () => {
const queryClient = useQueryClient();
/** GETの処理 */
const getPosts = async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
return res.data;
};
/** POSTの処理 */
const addPosts = async () => {
const res = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1,
});
alert(JSON.stringify(res.data, undefined, 4));
};
// Queries
const query = useQuery<Post[], Error>('posts', getPosts);
// Mutations
const mutation = useMutation(addPosts, {
onSuccess: () => {
// `posts`キーのクエリを無効化して再取得
queryClient.invalidateQueries('posts');
},
});
return (
<div>
<div className="container">
<button className="button" onClick={() => mutation.mutate()}>
Add Post
</button>
{query.isLoading || mutation.isLoading ? (
<div className="loader" />
) : (
query.data?.map((post) => (
<div className="card" key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))
)}
</div>
</div>
);
};
const App = () => {
const queryClient = new QueryClient();
return (
// ProviderでQueryClientを設定する
<QueryClientProvider client={queryClient}>
<Posts />
</QueryClientProvider>
);
};
export default App;
1. QueryClientを設定
const App = () => {
const queryClient = new QueryClient();
return (
// ProviderでQueryClientを設定する
<QueryClientProvider client={queryClient}>
<Posts />
</QueryClientProvider>
);
};
QueryClientProviderにQueryClientを設定して、コンポーネントを囲みます。
QueryClientはキャッシュのやり取りで使われます。
これを設定しないとエラーになるので、忘れないようにしましょう。
2. useQueryでデータ取得
const query = useQuer<取得するデータ型, Error>('ユニークなクエリキー', データ取得関数);
データを取得するときは、useQueryを使います。
指定する値は以下のようにしました。
/** GETの処理 */
const getPosts = async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
return res.data;
};
・・・
const query = useQuery<Post[], Error>('posts', getPosts);
- 取得するデータ型:Post[]
- ユニークなクエリキー:’posts’
- データ取得関数:getPosts
クエリキーの’posts’に紐づいて、データがキャッシュされます。
データが取得されるタイミングは、コンポーネントがマウントされた時です。
useQueryのdataやisLoadingを使えば、データを表示したりローディング状態の判定ができます。
<div className="container">
<button className="button" onClick={() => mutation.mutate()}>
Add Post
</button>
{query.isLoading || mutation.isLoading ? (
<div className="loader" />
) : (
query.data?.map((post) => (
<div className="card" key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))
)}
</div>
- isLoading:データ取得中はtrue、取得後にfalseになる
- data:取得したデータが入る。(ここではPost[])
このようにisLoadingとdataを使って、ローディング中の画面表示を実装することも可能です。
3. useMutationでデータ更新
const mutation = useMutation(データ更新関数, オプション);
データの更新は、useMutationで行います。
引数にはデータ更新関数とオプションを指定できます。
サンプルでは、POSTのレスポンスのデータをalertで表示する処理を定義しています。
const queryClient = useQueryClient();
・・・
/** POSTの処理 */
const addPosts = async () => {
const res = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1,
});
alert(JSON.stringify(res.data, undefined, 4));
};
・・・
// Mutations
const mutation = useMutation(addPosts, {
onSuccess: () => {
// `posts`キーのクエリを無効化して再取得
queryClient.invalidateQueries('posts');
},
});
今回は、オプションのonSuccessで成功時の処理を記載しています。
- onSuccess:リクエストが成功した場合の後処理を記述
- queryClient.invalidateQueries:
指定
キーのクエリを無効化して再取得
データの更新に成功した時に、データを再取得するような処理になります。
実行するときは、mutate()を呼び出します。
<div className="container">
<button className="button" onClick={() => mutation.mutate()}>
Add Post
</button>
{query.isLoading || mutation.isLoading ? (
<div className="loader" />
) : (
query.data?.map((post) => (
<div className="card" key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))
)}
</div>
- mutate():指定した関数を実行する
- isLoading:関数実行中はtrue、実行後にfalseになる
こちらも、ローディング中は画面の表示が切り替わるようにしています。
おわり
以上、React Queryの導入から使い方までを解説しました。
今回はちょっとしか触れませんでしたが、もっといろいろな活用方法があります。
ぜひ、使ってみてください。
コメント