GAミント至上主義

Web Monomaniacal Developer.

NuxtJS + Composition APIのuseAsync()でハマった3つ

新しいサイトの開発でNuxtJS + Composition API + TypeScriptで快適な開発をしてますがuseAsyncは、サーバー、クライアント両方で実行することもあり、理解にちょっと時間がかかっていろいろハマったのでメモ。

基本的にちゃんとドキュメント通りに使えば大丈夫なやつでした。あとasyncDataの代わりなので、そちらをちゃんと理解してればハマりにくそう。 はい、よくわかってません。

composition-api.nuxtjs.org

バージョンとか

"dependencies": {
    "@nuxtjs/axios": "^5.13.4",
    "@nuxtjs/composition-api": "^0.23.4",
    "core-js": "^3.12.1",
    "nuxt": "^2.15.6",
  },

※記事内のコードはてきとうにコピペして作ったので動きません。

useAsyncの中でいろいろしない

サンプルだとこんなシンプルな使い方してますが、ついつい中でrefの値セットしたりしてしまいます。
そうするとよく覚えてないけどサーバー側とブラウザ側で挙動がおかしくなります。

useAsyncの返り値を使いましょう。返り値の型がRefになるのも注意。


ドキュメントの様に、リクエストの結果を入れるだけにするのがよさそうです。

const posts = useAsync(() => $http.$get('/api/posts'))

だめな例1

setup() {
  const items = ref([])
  const fetchJob = () => {
      const response = $axios.$get<ApiResponse>(
        `/api/items`
      )
      items.value = response.items
  }
  useAsync(fetchJob)
  return { items }
}

リクエストの結果からいろいろ取り出して使いたいなってなったらcomputedでやるのがよさそうでした。

よさそうな例1

setup() {
  const fetchItems = () => {
      return $axios.$get<ApiResponse>('/api/items')
  }
  const response = useAsync(fetchItems)

  const items = computed(() => {
    if (!response.value) {
      return []
    }
    return response.value.items ?? []
  })
  return { items }
}

useAsyncにasync functionを渡さない

ドキュメントのサンプル通り、そのままPromiseを返さないとだめそうです。
どんな問題起きるかは忘れた。

だめな例2

setup() {
  const items = ref([])
  const fetchJob = async () => {
      return await $axios.$get<ApiResponse>(
        `/api/items`
      )
  }
  const response = useAsync(fetchJob)
}

ページ遷移のときに再実行が必要な場合はキーをつける

params等から値をとってAPIリクエストするのはよくやると思いますが、そのままだとSSR時は問題なくても、NuxtLink等でのページ遷移時はuseAsyncが動いてくれないことがありました。

ドキュメントの下の方に書いてありますが、再取得が必要な際は、userAsyncの第2引数にキーとなる文字列を渡す必要があります。

https://composition-api.nuxtjs.org/getting-started/gotchas/#keyed-functions

params.value.hogeの変更時にuseAsyncを動かす例

setup() {
  const { $axios, params } = useContext()
  const fetchItems = () => {
      return $axios.$get<ApiResponse>('/api/items', {params: {hoge: params.value.hoge}})
  }
  const response = useAsync(fetchJobs, params.value.hoge)
}

NuxtJS + Composition API + TypeScriptはまだ情報が少なく、ハマりやすいですが、ちゃんとドキュメント読めば結構大丈夫で、それ以上に快適という結論でした。
そこそこの規模の開発が今の所順調にできているので、個人的には現時点ではもうOption APIに戻る必要ないかなぁという感想です。

2021/7/7 追記

APIレスポンスでいろいろやりたいときはuseFetchを使うと良さそう。

https://composition-api.nuxtjs.org/lifecycle/useFetch

だけどcomputedをいっしょに使うと問題が・・・
Nuxt Composition APIのuseFetchとcomputedの問題について | polidog lab