【Nuxt3】axiosの代わりのuseFetch、$fetch、useAsyncDataの挙動の違い

シェアする:

この記事をおすすめしたい人

  • Nuxt3でAPIからデータを取得しようとしている人
  • axiosの代わりを探している人
  • つまりオレ

Nuxt v3の調査、axiosの代用編です。

axiosって、僕の理解ではウェブのAPI(JSON)からデータを取得する時に使うモジュールでした。 Nuxt2の時代でもfetchを使えばaxiosいらんやん!みたいになってどんどん使われなくなっていってました。

Nuxt3でも同様にaxiosじゃなくてNuxt内のコンポーザブルで同じことができるよーってことだったので、その辺のテストをしたいと思います。

以下、公式の解説に書かれている3つのデータ取得方法をメインに、Nuxt3でaxiosは使えなくなったのか、などを調べていきます。

useFetch

useFetchは戻り値のstatus.valueに取得結果のステータス(successで成功)、受け取った値はdata.valueに入っています。

変数urlにAPIのURLが入ってるものとして、Nuxt3式のscript setup (Composition API)の場合はこんな↓コード。


<script setup lang="ts">

const response = await useFetch(url)

if ( response.status.value == 'success' ) {
  console.log(response.data.value)
}

</script>

従来式のscript (Options API)で書くとこんな↓コード。


<script lang="ts">

export default defineNuxtComponent({
  async mounted() {
    const response = await useFetch(url)
    
    if ( response.status.value ) {
      console.log(response.data.value)
    }
  },
}

</script>

$fetch

$fetchは戻り値に直接データが入るようです。

script setup (Composition API)の場合はこんな↓コード。


<script setup lang="ts">

const response = await $fetch(url)

console.log(response)

</script>

script (Options API)で書くとこんな↓コード。


<script lang="ts">

export default defineNuxtComponent({
  async mounted() {
    const response = await $fetch(url)
    
    console.log(response)
  },
}

</script>

この書き方の場合、ステータスチェックができないようで、404などでエラーが出た場合は例外が投げられるようです。 なのでtryでくくらないといけないっぽい。

useAsyncData

useAsyncDataはそれ自体はAPI取得がどうのというものではなく、内側で$fetchを使うみたいです。 戻り値はuseFetchと同じ型で、status.valueに取得結果のステータス(successで成功)、受け取った値はdata.value。

script setup (Composition API)の場合はこんな↓コード。


<script setup lang="ts">

const response = await useAsyncData(async () => {
  return await $fetch(url)
})

if ( response.status.value == 'success' ) {
  console.log(response.data.value)
}

</script>

script (Options API)で書くとこんな↓コード。


<script lang="ts">

export default defineNuxtComponent({
  async asyncData() {
    const response = await $fetch(url)
    
    return response
  },
}

</script>

defineNuxtComponentの方は戻り値がComposition APIの方と違っていて、直接データが入るのでこちらは$fetchの方と同じ挙動。

たぶんこれ、defineNuxtComponentでもuseAsyncDataを使うのが同じやり方で、たぶんこっち↓が正解だと思います。


<script lang="ts">

  async mounted() {
    const response = await useAsyncData(async () => {
      return await $fetch(url)
    })
    
    if ( response.status.value ) {
      console.log(response.data.value)
    }
  },
}

</script>

これだと戻り値はuseFetchと同じ型になりました。 useAsyncDataはasyncDataの代わりというわけでもないんですね。

axiosは使えなくなっているのか?

使えました。

@nuxtjs/axiosの方ではなくて、ただのaxiosの方で試しています。 たぶんnuxtjsの方でもaxios本体はインストールされるはずなので問題ないかもですが、Nuxt3だとエラー出そうな気がしたので。

script setup (Composition API)の場合はこんな↓コード。


<script setup lang="ts">

import axios from 'axios'

const response = await axios.get(url)

console.log(response.data)

</script>

script (Options API)で書くとこんな↓コード。


<script lang="ts">

import axios from 'axios'

export default defineNuxtComponent({
  async mounted() {
    const response = await axios.get(url)
    
    console.log(response.data)
  },
}

</script>

どちらの書き方でも戻り値のstatusに200とかステータスコードが入るんですが、404なんかのエラーの場合get()が例外を投げるのでtryで括った方がよさそう。

結局どれがいいのか?

公式のAPIからのデータ取得について見てみると、axiosについて書かれていないのでaxiosは推奨されていないものとして、

  • useFetch:最もお手軽
  • $fetch:ユーザ入力を反映する場合はこれ
  • useAsyncData:$fetchとの組み合わせで細かい調整

みたいな感じに書かれています。 実際の書き方や挙動もそんな印象です。

僕が実際に使っていた例ではAPIからデータを取得するだけだったので、ステータスチェックも容易なuseFetchで十分そうでした。

実際に実装してみると、awaitで実行してるのにstatusに「idle」が入ることがあり(F5リロードした直後とか)、データを取得できていないケースが発生しました。 $fetchだと同じケースでこれが発生しなかったため、$fetchを採用することに。

今回テストしたケースとはまた別な形でAPIアクセスしているところがあるので、それを移植する際にもうちょっと追加テストをしておきます。

以上、WordPressからお届けしました!

シェアする: