Nuxt 3 useFetch ハマりポイント3つ
-
[id].vue
のページ、key を設定しないと違うIDのページで取得結果が更新されない -
useLazyFetch
にしないとページ遷移がスムーズじゃなくなる -
initialCache
がデフォで true
前提
10/18時点、"nuxt": "3.0.0-rc.11"
久しぶりに Nuxt を触った。Vue3, Nuxt3 をドキュメント見ながら使った。useFetch
がゆーたら Nuxt3 の目玉機能的なやつやと思うけど割とハマった。
[id].vue
のページ、key を設定しないと違うIDのページで取得結果が更新されない
1. 「key 渡さん場合、useFetch 書いてるファイル名と行番号を key にしますんで。」
If you do not provide a key, then a key that is unique to the file name and line number of the instance of useAsyncData will be generated for you.
(https://v3.nuxtjs.org/api/composables/use-async-data#params)
[userId].vue
の31行目に useFetch 書いてたからどんなIDだろうと key 一緒やんけ。やってんな。key を渡して解決。
useLazyFetch
にしないとページ遷移がスムーズじゃなくなる
2. 遷移先のページで useFetch
が発動すると取得が済むまで遷移してくれない。
By default, useFetch blocks navigation until its async handler is resolved.
Vue の Suspense
が関係しているんだろうか。
https://vuejs.org/guide/built-ins/suspense.html#async-dependencies'
useLazyFetch
を使うとすぐ遷移してくれる。ただし最初は取得結果が null なのを考慮してコードを書く必要がある。
initialCache
がデフォで true
3. false にしたら「常に最新の状態が反映される」から嬉しい気持ちになる。
useFetch も useAsyncData も、デフォルトでデータがキャッシュされ、同じkeyに対して一度リクエストしていたら、それ以降は再検証を行いません。
これはページ遷移などで別のコンポーネントがマウントされた場合も、共通のkeyであればAPIリクエストは行わず、キャッシュがそのまま使われます。明示的に refresh を呼ばれた場合のみ再検証が行われます。(数時間ページを開いたままでも更新されないのかなどは未検証です)
しかしこれでは SWR の「常に最新の状態が反映される」は実現できず、リロードするまで新しい結果は反映されません。
ここで、useFetch の第2引数、useAsyncData の第3引数である Options の中に、 initialCache というものがあります。デフォルト値は true です。
これを false にすると、ページ遷移などでコンポーネントが再度読み込まれた場合に、必ずAPIへのリクエストが行われます。
しかし、だからといって data がすぐにリセットされるわけではなく、APIリクエストが完了するまでは前回の取得結果をキャッシュとして表示し、データ取得が完了したタイミングで表示内容が更新されます。
おまけ
useFetch 共通化したやつ。最初 key 設定せずに共通化したのを使い回して「投稿取得したつもりがユーザー情報が表示されるぞ?」みたいなことなった。
type UseLazyFetch = typeof useLazyFetch
export const useApi: UseLazyFetch = (url, options) => {
const config = useRuntimeConfig()
return useLazyFetch(url, {
baseURL: config.public.apiBase,
key: url as string,
initialCache: false,
...options,
})
}
Discussion