🚀

【urql】useQueryを使って任意のタイミングでフェッチする方法

2025/01/15に公開

こんばんは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を設定するとキャッシュを無視して常に最新のデータを取りに行く

React/Preact Bindings|urlqドキュメント

Discussion