SAKURUG TECHBLOG

【Nuxt3rc】useFetchの結果が重複してしまう原因

timestampauthor-name
Kota

はじめに

こんにちはKotaです。

今回は、Nuxt3のrc版で開発を行っている中で経験した表題の件について、サンプルをもとに原因と対策をご紹介します。

fetchの結果が重複するケース

まず、表題の事象が発生した状況を簡易的に再現します。
再現方法としては「本techblogの最新記事(現時点)を2件取得し、各タイトルを画面に表示させる」こととします。
今回は、rc版(v3.0.0-rc.11)、stable版(v3.2.3)の2つのリポジトリで同様の処理を行い、その結果を比較することで挙動の違いを見ていきます。

関連ディレクトリ

  • ~/composables/useArticle.js
  • ~/components/ArticleTitle.vue
  • ~/pages/index.vue


ソースコード

useArticle.js

export const useArticle = async articleId => {
  const config = useRuntimeConfig()
  const { data, error } = await useFetch(`/articles/${articleId}`, {
    baseURL: config.cmsUrl,
    headers: {
      'API-KEY': config.cmsKey
    }
  })

  if (error.value) throw error.value

  return data.value
}


ArticleTitle.vue

<script setup>
const props = defineProps({
  articleId: String,
})
const article = await useArticle(props.articleId)
</script>

<template>
  <h2>{{ article.title }}</h2>
</template>


index.vue

<template>
  <ArticleTitle article-id="minute-report" />
  <ArticleTitle article-id="eu-outlook" />
</template>


rc版とstable版での結果の比較

結果:rc版


結果:stable版



上記の結果の比較より、全く同じソースコードでも結果が異なることが分かりました。
rc版では1件目と2件目の結果が重複しているようです。
では、その原因を見ていきましょう。

fetchの結果が重複する原因

rc版で結果が重複してしまう原因は、fetchオプションとしてkeyが宣言されていないことによるものです。
反対に、stable版で結果が重複していない理由はkeyの仕様が変更されたからです(rc14~)。

keyの初期値に関する仕様(~rc13)

  • useAsyncData, useFetch:インスタンス化しているファイル名とその行番号


keyの初期値に関する仕様(rc14~)

  • useAsyncData:インスタンス化しているファイル名とその行番号
  • useFetch:fetchリクエスト時のURLとそのパラメーターの値


該当のリリースドキュメントを確認すると、
『rc6以降で、useFetchの2回目以降の結果が最初の1回目の結果と重複している』というissueが立ち上がっていたことが分かります。

つまり、僕が実際に遭遇した事象は既に問題提起~解決済みでした。

対策

以上を踏まえた対策としては、

  • Nuxtのバージョンを更新する
  • rc版(~rc13)で継続して開発するのであれば、useFetchを仕様する時はオプションとしてkeyを宣言する

で対応可能です。

参考として、keyを指定した場合のソースコードのサンプルです。

const { data } = await useFetch(`/articles/${articleId}`, {
  key: articleId,
  baseURL: config.cmsUrl,
  headers: {
    'API-KEY': config.cmsKey
  }
})


補足

keyとしてdate.now()などdateオブジェクトの値を指定すると、処理の結果が安定せず重複してしまうケースがありました。
keyを指定したuseFetchのサンプルを、useAsyncDataで置き換えると下記のようになります。

const { data } = await useAsyncData(articleId, () =>
  $fetch(`/articles/${articleId}`, {
    baseURL: config.cmsUrl,
    headers: {
      'API-KEY': config.cmsKey,
    },
  })
);


まとめ

今回はuseFetchを事例として、rc版とstable版における挙動と仕様の違いを整理しました。

個人的な学びとしては、

  • 自分が扱っている技術のバージョンリリースに関するドキュメントは丁寧に確認する
  • 実際に検証してみたりしながら常に最新の知識を持っておく

この2つの必要性を強く感じました。

他にも仕様が大きく変更されたものはありますが、本記事がNuxt3でプロダクトを開発している方にとって少しでも参考になれば幸いです。

記事をシェアする

ABOUT ME

author-image
Kota
新卒入社3年目。SAKURUG TECHBLOG管理者。社内業務システムやフロントエンド開発を行っています。

© SAKURUG co.,ltd.