みなさん一度は「Blitz.js」というRailsにインスパイアされて作られたフルスタックReactフレームワークを聞いたことがあるのではないでしょうか。 触ったことがない方は是非触ってみてください。
本記事ではタイトルにあるように実際に使用したquery情報をまとめてみました。 また、Blitz.js は next + prisma で railsのようにフルスタックなフレームワークを実現しているので、Blitzの理解のためにもprismaとnextを理解していると学習が捗ること間違いなしです。
ちなみにドキュメントにも以下の記載があるようにuseQueryはreact-queryを基に構築されているため、 自動キャッシュや、クエリ結果が古ければ再クエリを行うような機能も充実してます。
useQuery is built on react-query, so it automatically provides awesome features such as automatic caching and revalidation ※ 個人的にはキャッシュを有効活用することで表示パフォーマンスを上げれるのがreact-queryの1番のメリットだと感じている
補足として、それらの機能を利用する上でデフォルトの設定がされているクエリが複数存在しているため、想定外の結果になる場合はドキュメントに一度目を通して見ることをオススメします。
Out of the box, useQuery and the other query hooks are configured with aggressive but reasonable defaults. Sometimes these defaults can catch new users off guard or make learning/debugging difficult if they are unknown by the user.:
実際に使ったQueryオプション
refetchOnWindowFocus
用途: window フォーカス時にデータが更新されてたらrefetchをしたい(true)・したくない時(false) window フォーカス時にrefetchをしたい(always) ※デフォルトはtrue
使い方:
デフォルト const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnWindowFocus: true}) 例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnWindowFocus: false}) 例2: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnWindowFocus: "always"})
実際に起きたケース
- form入力を行うページで別タブへ移動した後、form入力画面へ戻ってきたらrefetchが発生してしまい、入力していた情報が消えてしまった。
実際のコード
const [project] = useQuery(getProject, projectId, { refetchOnWindowFocus: false, refetchOnReconnect: false, })
公式ドキュメントに以下の記載があるように、上記のようなケースを防ぐ場合はrefetchOnWindowFocus
とrefetchOnReconnect
をoptionとして付与してあげる必要があるとのことでした。
Stale queries will automatically be refetched in the background when the browser window is refocused by the user or when the browser reconnects. You can disable this using the refetchOnWindowFocus and refetchOnReconnect options in queries.
enabled
用途 クエリAが処理完了次第、クエリQueryBをトリガーしたい
使い方
const [user] = useQuery(getUser, { where: { id: props.query.id } }) const [projects] = useQuery(getProjects, { where: { userId: user.id } }, { enabled: user }))
実際に起きたケース
- 処理Aが完了後に確定する結果によって任意のデータを取得したかった。
実際のコード
const projects = useQuery( getProjects, { where: getProjectsWhereParams, orderBy: { projectNumber: 'asc', }, }, { enabled: !!getProjectsWhereParams, ← refetchOnWindowFocus: false, refetchInterval: false, }, );
以上が実際に開発で使ったQueryオプション達でした。 上記以外にも有用そうなオプションをいくつか公式ドキュメントから紹介したいと思います。 blitzjs.com
retry
用途: クエリの実行結果が失敗だったら再クエリしたい
使い方:
const [user] = useQuery(getUser, { where: { id: props.query.id } }, {retry: true})
retryOnMount
用途: falseに設定するとエラーが含まれている場合、クエリはマウント時に再試行されない。 ※デフォルトはtrue
使い方:
const [user] = useQuery(getUser, { where: { id: props.query.id } }, {retryOnMount: false})
retryDelay
用途: retryするタイミングをミリ秒単位で設定できる(遅らせることができる)
使い方:
例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {retryDelay: 1000}) 例2: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {retryDelay: attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)})
cacheTime
用途: クエリのキャッシュ保持時間を設定できる(キャッシュしたくない場合にミリ秒単位で時間を指定することでキャッシュを廃棄できる)
Infinity
を設定すると廃棄しない使い方:
例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {cacheTime:: 1000}) 例2: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {cacheTime: Infinity})
refetchInterval
用途: クエリをミリ秒単位で定期的に行える
使い方:
例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchInterval: 1000})
refetchIntervalInBackground
用途: タブ/windowがバックグランド時にrefetchIntervalを行う
使い方:
例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchIntervalInBackground: true})
refetchOnMount
用途: マウント時にデータが更新されてたらrefetchをしたい(true)・したくない時(false) マウント時にrefetchをしたい(always) ※デフォルトはtrue
使い方:
デフォルト const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnMount: true}) 例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnMount: false}) 例2: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnMount: "always"})
refetchOnReconnect
用途: データが古くなっている場合、再接続時にrefetchしたい(true)・したくない時(false) 再接続時にrefetchしたい(always) ※デフォルトはtrue
使い方:
デフォルト const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnReconnect: true}) 例1: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnReconnect: false}) 例2: const [user] = useQuery(getUser, { where: { id: props.query.id } }, {refetchOnReconnect: "always"})