【urql】useQueryを使って任意のタイミングでフェッチする方法
こんばんはmayaです!
自分が今所属してるプロジェクトではデータフェッチにGraphQLを採用しており、クライアントライブラリにはurqlを使っています。
今日の業務でタイトル通りの実装をしたいケースに遭遇しまして、urqlでのデータフェッチについて少し調べてみたので備忘録的にまとめます!
useQueryの基本的な使い方
こんな感じで使うことが多いと思います。
const TodosListQuery = gql`
query ($name: String!, $age: Int!) {
...
}
`;
const Todos = ({ name, age }) => {
const [{data, fetchin, error}] = useQuery({
query: TodosListQuery,
variables: { name, age },
});
///
}
引用:React/Preact Bindings | urlq ドキュメント
variablesで指定した変数が変更されるとデータフェッチされるという仕組みです。
初回のレンダリングに合わせて画面表用のデータを取得するとか、そういった単純なケースであればこれだけで十分だと思います。
任意のタイミングで実行したいケース
例えば検索フォームなどにおいて、ユーザーが検索条件を入力→送信ボタンを押した時にデータ取得を行いたいケースを考えます。
ひとまずこんな感じで実装してみました
const Searchs = ({ name, age }) => {
const [conditions, setConditons] = useState({...})
const [{data, fetchin, error}] = useQuery({
query: SearchQuery,
variables: conditions,
});
///
}
でもこれじゃダメです。
検索条件を保持するstateをそのままvariablesに指定すると、setCondionsする度(stateが更新される度)にvariablesが変更を検知して、データフェッチを走らせてしまいます。
つまり、ユーザーが一文字入力するたびに検索が走ってしまいます。これじゃだめです(そういった仕様が適しているサイトもあるけど)
そんな時はreexecuteQueryを使おう
useQueryのreexecuteQuery関数は、任意のタイミングでデータフェッチを行うための関数です。
このようにして使います。
const Searchs = ({ name, age }) => {
const [conditions, setConditons] = useState({...})
const [{data, fetchin, error}, reexecuteQuery] = useQuery({
query: SearchQuery,
variables: conditions,
});
const refetch = () => {
reexecuteQuery({ requestPolicy: 'network-only' });
}
///
}
reexecuteQuery関数には強制的にuseQueryを起動させる作用がありまして、さらに上のコードではrequestPolicyにnetwork-only
を指定することでキャッシュを無視してデータを取得しています。
これで、ボタンのonClickにrefetch()メソッドを設定すれば、ユーザーが検索ボタンを押したタイミングでデータフェッチを行えるようになります。
まとめ
urqlのuseQueryには下記のようなオプションがあって組み合わせるといろんなシーンのデータフェッチに対応できると思うので、ぜひ公式サイトで確認してみてください。
-
pause
:データ取得を特定の条件でスキップさせる。trueを設定すると一生スキップする -
requestPolicy
:キャッシュの利用方法。network-only
を設定するとキャッシュを無視して常に最新のデータを取りに行く
Discussion