Open9

React QueryのDocを読む

KeitaUenishiKeitaUenishi

従来までのstate管理ライブラリの多くは、クライアントのstateを扱うことには優れているが、非同期やサーバーのstateを扱うことは苦手だった。

React Queryを使用することによって、どのような効果が期待できるか

On a more technical note, React Query will likely:
・Help you remove many lines of complicated and misunderstood code from your application and replace with just a handful of lines of React Query logic.
・Make your application more maintainable and easier to build new features without worrying about wiring up new server state data sources
・Have a direct impact on your end-users by making your application feel faster and more responsive than ever before.
・Potentially help you save on bandwidth and increase memory performance

より技術的なことを言えば、React Queryは次のようなことを可能にするでしょう:
・アプリケーションから複雑で誤解されやすいコードを削除し、わずか数行のReact Queryロジックに置き換えることができます。
・アプリケーションの保守性が向上し、新しいサーバー状態のデータソースの配線を心配することなく、新機能を簡単に構築できるようになる。
・アプリケーションがこれまで以上に高速で応答性が高くなるため、エンドユーザーに直接的な影響を与える。
・帯域幅を節約し、メモリ性能を向上させる可能性がある。

https://tanstack.com/query/v3/docs/framework/react/overview#motivation

KeitaUenishiKeitaUenishi

devtoolsを導入する(react-queryがインストールされていればimport可能)

import { ReactQueryDevtools } from 'react-query/devtools'

QueryClientProvider 内に、ReactQueryDevtools を配置することで、useQueryで設定したユニークキーごとのクエリに関する情報を確認することができる。

import { ReactQueryDevtools } from 'react-query/devtools'

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* The rest of your application */}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}

画面左下にこんな感じのマークが出てくる

KeitaUenishiKeitaUenishi

important defaults
https://tanstack.com/query/v3/docs/framework/react/guides/important-defaults

Out of the box, React Query is configured with aggressive but sane defaults. Sometimes these defaults can catch new users off guard or make learning/debugging difficult if they are unknown by the user. Keep them in mind as you continue to learn and use React Query

既成概念にとらわれない、React Queryは、アグレッシブだがまともなデフォルトで設定されている。 時々、これらのデフォルトは新しいユーザーを油断させたり、ユーザーが知らない場合、学習/デバッグを困難にすることがあります。React Queryの学習と使用を続ける際には、これらのことを覚えておいてください。

Query instances via useQuery or useInfiniteQuery by default consider cached data as stale.
To change this behavior, you can configure your queries both globally and per-query using the staleTime option. Specifying a longer staleTime means queries will not refetch their data as often
Stale queries are refetched automatically in the background when:
・New instances of the query mount
・The window is refocused
・The network is reconnected.
・The query is optionally configured with a refetch interval.

useQuery または useInfiniteQuery を使用したクエリ・インスタンスは、デフォルトでキャッシュされたデータを stale とみなします。 この動作を変更するには、staleTime オプションを使用して、クエリをグローバルおよびクエリごとに設定できます。 staleTime を長く指定すると、クエリは頻繁にデータをリフェッチしなくなります。 古いクエリは、以下の場合にバックグラウンドで自動的にリフェッチされます。
・クエリの新しいインスタンスがマウントされる
・ウィンドウがリフォーカスされる
・ネットワークが再接続される
・クエリは、オプションでリフェッチ間隔を設定できます。

If you see a refetch that you are not expecting, it is likely because you just focused the window and React Query is doing a refetchOnWindowFocus. During development, this will probably be triggered more frequently, especially because focusing between the Browser DevTools and your app will also cause a fetch, so be aware of that.
To change this functionality, you can use options like refetchOnMount, refetchOnWindowFocus, refetchOnReconnect and refetchInterval.

Query results that have no more active instances of useQuery, useInfiniteQuery or query observers are labeled as "inactive" and remain in the cache in case they are used again at a later time.
By default, "inactive" queries are garbage collected after 5 minutes.

予期しないリフェッチが表示された場合は、ウィンドウにフォーカスが当たったため、React QueryがrefetchOnWindowFocusを実行している可能性があります。 開発中、これはおそらくより頻繁にトリガーされるでしょう。特に、Browser DevToolsとアプリの間でフォーカスを合わせると、フェッチも発生するので、注意してください。

この機能を変更するには、refetchOnMount、refetchOnWindowFocus、refetchOnReconnect、refetchIntervalなどのオプションを使用します。 useQuery、useInfiniteQuery、またはクエリ・オブザーバのアクティブなインスタンスがなくなったクエリ結果は、"非アクティブ "としてラベル付けされ、後で再び使用される場合に備えてキャッシュに残ります。 デフォルトでは、"非アクティブ "クエリは5分後にガベージコレクションされます。

KeitaUenishiKeitaUenishi

Queries

A query is a declarative dependency on an asynchronous source of data that is tied to a unique key. A query can be used with any Promise based method (including GET and POST methods) to fetch data from a server. If your method modifies data on the server, we recommend using Mutations instead.

クエリとは、一意のキーに結びついた非同期データソースに対する宣言的な依存関係です。 クエリは、Promise ベースのメソッド (GET メソッドや POST メソッドを含む) で使用することができます。 メソッドがサーバ上のデータを変更する場合は、代わりMutationを使用することをお勧めします。

クエリを実行するためのhooksであるuseQueryは、以下のように宣言する。

const result = useQuery('todos', fetchTodoList)
  • 第1引数には「クエリの一意キー」
  • 第2引数には「データフェッチを行うようなPromiseを返却する関数」
    を渡す。

・error - If the query is in an isError state, the error is available via the error property.
・data - If the query is in a success state, the data is available via the data property.
・isFetching - In any state, if the query is fetching at any time (including background refetching) isFetching will be true.

For most queries, it's usually sufficient to check for the isLoading state, then the isError state, then finally, assume that the data is available and render the successful state:

・error - クエリが isError 状態の場合、error プロパティでエラーが確認できます。
・data - クエリが success 状態の場合、data プロパティでデータが確認できます。
・isFetching - どの状態でも、クエリがフェッチしている場合(バックグラウンド・リフェッチを含む)、isFetching は true になります。

ほとんどのクエリーでは、isLoading状態をチェックし、次にisError状態をチェックし、最後にデータが利用可能であると仮定してsuccessful状態をレンダリングすれば十分である。

クエリ実行によって取得した最終的なデータは data プロパティにて確認できる。

KeitaUenishiKeitaUenishi

Query Keys

At its core, React Query manages query caching for you based on query keys. Query keys can be as simple as a string, or as complex as an array of many strings and nested objects. As long as the query key is serializable, and unique to the query's data, you can use it!

React Queryの中核は、クエリ・キーに基づいてクエリのキャッシュを管理することです。 クエリキーは、文字列のような単純なものから、多くの文字列やネストされたオブジェクトの配列のような複雑なものまであります。 クエリ・キーがシリアライズ可能で、クエリのデータに対して一意である限り、それを使用することができます!

クエリキーはuseQueryに文字列をひとつ渡したとしても、内部的に配列に変換される

// A list of todos
useQuery('todos', ...) // queryKey === ['todos']

// Something else, whatever!
useQuery('somethingSpecial', ...) // queryKey === ['somethingSpecial']

https://tanstack.com/query/v3/docs/framework/react/guides/query-keys#string-only-query-keys

KeitaUenishiKeitaUenishi

Window Focusによるrefetchの制御方法について

If a user leaves your application and returns to stale data, React Query automatically requests fresh data for you in the background. You can disable this globally or per-query using the refetchOnWindowFocus option:

ユーザーがアプリケーションを離れて古いデータに戻った場合、React Queryはバックグラウンドで自動的に新しいデータを要求します。 refetchOnWindowFocusオプションを使用して、これをグローバルまたはクエリごとに無効にできます:

https://tanstack.com/query/v3/docs/framework/react/guides/window-focus-refetching

KeitaUenishiKeitaUenishi

Query Invalidation

Waiting for queries to become stale before they are fetched again doesn't always work, especially when you know for a fact that a query's data is out of date because of something the user has done. For that purpose, the QueryClient has an invalidateQueries method that lets you intelligently mark queries as stale and potentially refetch them too!

クエリが古くなるのを待ってから再取得するのは、必ずしもうまくいくとは限りません。特に、ユーザが何かしたためにクエリのデータが古くなったという事実がわかっている場合はなおさらです。 そのため、QueryClient には invalidateQueries メソッドが用意されており、クエリを古いと判断して再取得することができます!

https://tanstack.com/query/v3/docs/framework/react/guides/query-invalidation