猿でもわかる！！Nuxt.js の fetch と AsyncData の違い

# ど初心者向け

Nuxt.jsを0から勉強している私にとって、fetchとAsyncDataは書き方も似てるしドキュメント読んでもよくわからないカタカナで煙に巻かれた感じであんまりよくわからない...となっていました。

もし同じような境遇のいたら参考にしていただければと思います。玄人さんにとっては当たり前の話ですので読んでも不快かもしれません。

# fetch ??　AsyncData ??
まずは公式ドキュメントの説明を見てみましょう。

## fetch
>fetch メソッドは、ページがレンダリングされる前に、データをストアに入れるために使われます。コンポーネントのデータをセットしないという点を除いては asyncData メソッドとよく似ています。
fetch メソッドが設定されている場合、コンポーネント（ページコンポーネントに限ります）がロードされる前に毎回呼び出されます。サーバサイドでは一度だけ呼び出され（Nuxt アプリケーションへの最初のリクエスト時）、クライアントサイドでは他のルートへ移動したときに呼び出されます。
fetch メソッドは第一引数として context オブジェクトを受け取るので、データを取得し、取得したデータをストアに入れることができます。fetch メソッドを非同期にするためには Promise を返却してください。そうすれば nuxt.js はコンポーネントがレンダリングされる前に promise が解決されるまで待機します。

### 書き方

```index.vue
<script>
export default {
  fetch ({ store, params }) {
    return axios.get('http://my-api/stars')
    .then((res) => {
      store.commit('setStars', res.data)
    })
  }
}
```

## asyncData
> 場合によっては、ストアを使用せずにデータをフェッチし、サーバー上でプレレンダリングしたい場合があります。 asyncData は ページ コンポーネントがローディングされる前に常に呼び出されます。サーバーサイドでは 1回だけ（Nuxt アプリへの最初のリクエスト）呼び出され、クライアントサイドではページ遷移をするたびに呼び出されます。このメソッドは、第一引数としてコンテキストを受け取ります。これを使用してデータを取得し、 Nuxt.js はコンポーネントデータとマージすることができます。
Nuxt.js は返されたオブジェクトとコンポーネントデータを自動的にマージします。

```index.vue
<script>
export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        return { title: res.data.title }
      })
  }
}
</script>
```

どうでしょうか？**「説明はよくわからないカタカナが多いしとりあえず書き方だけ見てみよう」**と思った初心者にを殺しにくるような似ている書き方ですよね。私も無事殺されて絶望した覚えがあります。

では一緒に解読していきましょう。

# 頑張って説明を読んでみる
## まずはfetchから
実は最初の2文に全てが詰まっています。
>fetch メソッドは、ページがレンダリングされる前に、データをストアに入れるために使われます。コンポーネントのデータをセットしないという点を除いては asyncData メソッドとよく似ています。

**データをストアに入れる**という表現を理解するには、少し**vuex**についての知識が必要です。簡単にいうと、vuexというモジュールを使うことによって**全てのコンポーネントからアクセス可能な共有変数スペースを利用できるようになります。**これがstoreディレクトリ内にあるので、データをストアに入れる、という表現になっています。
つまり、さっきの引用を噛み砕いて説明すると、

>**fetchメソッドは、ページが描画される前に行われ、共有スペースの変数にデータを代入したい時に使われます。コンポーネントのデータをセットしないという点を除いてはasyncDataメソッドとよく似ています。**

ストアに保存するという作業は上記の引用コード内のこの部分で行われています。

```index.vue
<script>
export default {
  fetch ({ store, params }) {
    return axios.get('http://my-api/stars')
    .then((res) => {
      //ここでストアに保存している！！！！！！！！！！！！
      store.commit('setStars', res.data)
    })
  }
}
```

では次に、公式にも**似ている**と書かれているasyncDataメソッドについて見ていきましょう。

## asyncData
これも最初の一文に全てが詰まっています。
>場合によっては、ストアを使用せずにデータをフェッチし、サーバー上でプレレンダリングしたい場合があります。
......
これを使用してデータを取得し、 Nuxt.js はコンポーネントデータとマージすることができます。
Nuxt.js は返されたオブジェクトとコンポーネントデータを自動的にマージします。

特に
**ストアを使用せずに**
の部分が大事です。

もう分かったでしょうか。asyncDataもページがレンダリングされる前に呼び出されるメソッドですが、axiosなどを利用して**手に入れたデータを共有変数スペースのstoreに保存せずにそのコンポーネントのデータとして格納したい時に使う**メソッドがasyncDataです。引用の最後の二文にも書かれていますが、asyncDataによってreturnされたデータはコンポーネントのデータと自動的に接続されます。上記の引用コードのこの部分ですね。

```index.vue
<script>
export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        // ここで取得データをコンポーネントデータに格納してる！！！！！！！
        return { title: res.data.title }
      })
  }
}
</script>
```

# 違う部分と似ている部分
以上の説明を読んだ皆さんならもうお分かりだと思いますが、fetchとasyncDataの違いは、

- **fetch**:取得したデータをstoreに保存するためのメソッド
- **asyncData**: storeを経由せずにコンポーネントのデータとして保存するためのメソッド

というものです。一方で似ている部分もあって、

- ページがレンダリングされる前に呼び出される
- fetchを非同期メソッドにすると最後の処理以外書き方が一緒になる

という類似点があります。一つ目ののプレレンダリングで呼び出されるという特徴ゆえ、どちらのメソッド内でも**メソッド内の this を通してコンポーネントのインスタンスにアクセスすることは できません。**これはコンポーネントが インスタンス化される前に このメソッドが呼び出されるからです。（公式ドキュメントより引用）

では皆さんのnuxt.jsライフが良いものになることを祈ってこの記事を終わらせていただきます。参考になったという人は「いいね」していただけるととても嬉しいです！！