インストール
react-qureryとdevtoolsをインストールしておくと便利です。
1 2 |
npm install react-query npm install react-query-devtools |
react-query-devtools
導入するとブラウザ左下でデバッガーのようなものが出ます。React-Queryで開発していくのであれば非常に便利なツールです。
App.tsxへの導入
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 } from 'react' import { QueryClient, QueryClientProvider } from 'react-query' import { ReactQueryDevtools } from 'react-query/devtools' import { BrowserRouter, Route, Switch } from 'react-router-dom' import { ReactQueryを導入するコンポーネント名 } from './components/ReactQueryを導入するコンポーネント名' const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false, suspense: true, // React18からの機能なので注意 }, }, }) const App: VFC = () => { return ( <QueryClientProvider client={queryClient}> <BrowserRouter> <Switch> <Route exact path="/"> <ReactQueryを導入するコンポーネント名 /> </Route> </Switch> </BrowserRouter> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ) } export default App |
QueryClient
オプションをいくつか設定できます。ここで適用したオプションはクライアント内の全てのQueryに適用されます。
オプション名 | 説明 |
---|---|
retry | デフォルトで3回まで失敗してもフェッチをする設定になっていますが、falseを指定すれば無効化できます。 |
refetchOnWindowFocus | デフォルトでユーザーがブラウザのコンポーネントにフォーカスを当てた時に自動でフェッチが動くようになっています。レンダリングが多く行われることになりかねないので、できればfalseにしておくのが望ましいでしょう。 |
suspense | React18からの機能です。 |
<ReactQueryDevtools initialIsOpen={false} />
ReactQueryのdevtoolを有効化できます。
InitialsOpen
trueだとブラウザを開いた時に自動で起動します。falseだと閉じた状態にできます。
カスタムフックの記述方法
useQuery用のカスタムフックは以下のように記述します。useQueryというフックを使ってAPIからのfetchを行うことになります。
なお、useQueryが動くタイミングとしては後述する呼び出すコンポーネントがマウントされたタイミングになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { useQuery } from 'react-query' import axios from 'axios' const getXXX = async () => { const { data } = await axios.get<フェッチするデータのデータ型[]>('APIのURL') return data } export const useQueryXXX = () => { return useQuery<フェッチするデータのデータ型[], Error>({ queryKey: 'xxx', queryFn: getXXX, cacheTime: 10000, staleTime: 0, }) } |
引数 | 説明 |
---|---|
queryKey | ReactQueryのキーです。好きな名前をつけれます。(例:Tasksなど) |
queryFn | 非同期の関数を指定します。 |
cacheTime | ミリ秒の単位で指定します。useQueryしているコンポーネントがアンマウントされた場合に指定した時間経過後にキャッシュが削除される挙動になります。デフォルトで5分が設定されています。これは特別な理由がなければデフォルトの値で問題ないと思いますので指定をしなくても良いかもしれません。 ガベージコレクションで不要なメモリを削除してくれるというメリットがあります。 |
staleTime | ミリ秒の単位で指定します。例えば、10000を指定した場合は10秒になります。指定した時間経過後にサーバーに再度fetchを行う挙動になります。 3までは自動再レンダリングが行われる仕様でしたが、4からは自動ではなくなりました。 |
refetchOnWindowFocus
| デフォルトでユーザーがブラウザのコンポーネントにフォーカスを当てた時に自動でフェッチが動くようになっています。レンダリングが多く行われることになりかねないので、できればfalseにしておくのが望ましいでしょう。 |
refetchInterval | 再フェッチしたい場合の秒数を指定します。自動でその秒数後フェッチしてくれます。 |
staleTime
Infinity
自分、もしくは他人の誰かが更新したデータが影響しあう可能性がない場合はこれを指定します。無限という意味になり、一定間隔でサーバーにデータをfetchすることを防止します。プライベートなアプリケーションなどではこの設定でも良さそうです。
fetchするタイミングとしては、初期表示時もしくは自分でデータを更新したタイミングのどちらかになります。
呼び出すコンポーネント側
reactQueryで結果を呼び出す側では下記のような感じで記述します。
1 2 3 4 5 6 7 8 9 10 |
import { useQueryXXX } from '../useQueryXXX' export const コンポーネント名: VFC = () => { const { status, data } = useQueryXXX() return ( <> {data} </> ) } |
戻り値 | 説明 |
---|---|
status | 通信のステータスが入ります。なお、この中にloadingやerrorなども持っており、余分なuseStateをコンポーネント側に持たせる必要がなくなるので再レンダリングの対策にもなります。 |
data | fetchしたデータが入ります。 |
キャッシュデータを取得する書き方(getQueryData)
useQueryでデータをキャッシュしますが、キャッシュしたデータを取得する場合は下記のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 |
import { VFC } from 'react' import { useQueryClient } from 'react-query' export const ReactQueryB: VFC = () => { const queryClient = useQueryClient() const data = queryClient.getQueryData<フェッチするデータ型[]>('queryKeyを指定') return ( <> {data} </> ) }な |
getQueryDataの注意点
なお、useQueryでfetchする場合に比べてgetQueryDataによるキャッシュの取得は最新データをリアルタイムに更新するところまではやってくれないので注意です。useQueryは毎回キャッシュに変更があるか検知して再レンダリングしてくれます。
なので、使い所としては、データ登録API実行後の再レンダリングする際の事前データ取得処理などに限られます。
通常の表示処理などではgetQueryDataではなくuseQueryを使用するようにしましょう。
ステータスを閲覧できるツール
「ReactQueryDevtools」というライブラリを使えば、React Queryによって今取得したデータがどのようなステータスになっているか確認できます。
また、このツールを使えば、React Queryで取得したデータの一覧も確認できます。
React Queryのステータス
fresh
最新のデータとみなす。この状態の際は、何度リクエストしたとしてもキャッシュデータが使われてサーバーへのフェッチが行われません。staleTimeで指定した秒数経過したらfresh→staleという状態に移動します。
fetching
サーバーからデータを取得中の状態です。通常のネットワーク速度だと一瞬しか表示されないです。
stale
キャッシュが古い物だとみなしている状態のことです。staleTimeで指定した時間が経過した後にこのステータスに移ります。
なお、仮にstaleTimeが経過していたとしても一旦こちらのデータを画面に表示させます。その後、REST APIの方からデータを取得して再描画が行われます。
Inactive
キャッシュからデータを取得している状態です。
この記事へのコメントはありません。