2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

useSWRで同一ファイルで複数のデータを取得する際にdataという変数がダブってしまう時の対処法

Posted at

今回やりたいこと

今回やりたいことはタイトルにもある通り、同一ファイル内でuseSWRを使って複数のデータをフェッチする際にdataという変数がダブってしまう問題についてどう解消すればいいのか紹介したいと思います。

実践

今回はJSONPlaceholderを例に行っていきます。
JSONPlaceholderから記事を取得してきて取得したデータを表示したいとします。

こちらのコードはuseSWRの基本的な使い方をしており、他の技術記事でも使い方についてはこのような例が多いかと思われます。(SWRの使い方についてまだ知らないよって方はこちらの記事をご覧ください)

'use client'

import useSWR from 'swr'

const Page = () => {
  const fetcher = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts/1').then(
        (response) => response.json()
      )

      return response
    } catch (error) {
      console.error(error)
      return null
    }
  }

  const { data } = useSWR(`https://jsonplaceholder.typicode.com/posts/1`, fetcher)

  return (
    <>
        <p>タイトル</p>
      <p>{data && data.title}</p>
    </>
  )
}
export default Page

単一のAPIを叩いてそれを出力したい場合は上記のコードのように書けば問題ありません。ですが、タイトルだけでなく、コメントも出力したい場合はどうでしょう?

コメントは別のAPIを叩いてデータをフェッチする必要があり、以下のようなコードを書けば良いかもしれません。

'use client'

import useSWR from 'swr'

const Page = () => {
  const fetcher = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts/1').then(
        (response) => response.json()
      )

      return response
    } catch (error) {
      console.error(error)
      return null
    }
  }

  const { data } = useSWR(`https://jsonplaceholder.typicode.com/posts/1`, fetcher)

  const fetcher = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts/1/comments').then(
        (response) => response.json()
      )

      return response
    } catch (error) {
      console.error(error)
      return null
    }
  }

  const { data } = useSWR(`https://jsonplaceholder.typicode.com/todos/1/comments`, fetcher)

  return (
    <>
      <p>タイトル</p>
      <p>{data && data.title}</p>
      {data &&
        data.map((item) => (
          <div key={item.id}>
            <p>name: {item.name}</p>
            <p>comment: {item.body}</p>
          </div>
        ))}
    </>
  )
}
export default Page

こちらのコードを書けば一見動くように見えるかもしれませんが、実はこのコードでは動きません。
the name `fetcher` is defined multiple timesというエラーもしくはthe name `data` is defined multiple timesというエラーが出ます。
お気づきの方も多いと思いますが、dataという変数名とfetcherという関数名が複数回定義されているため先ほどのエラーが出るのです。

ではどうやってこのエラーを解決するのか?
解決方法は簡単です。datafecterにオリジナルの名前をつけてあげればいいのです。
言葉でまず説明するよりもコードを見たほうが早いと思うのでコードを見てみましょう。
以下が期待通りに動くコードになります。

'use client'

import useSWR from 'swr'

const Page = () => {
  const postFetcher = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts/1').then(
        (response) => response.json()
      )

      return response
    } catch (error) {
      console.error(error)
      return null
    }
  }

  const { data: post } = useSWR(`https://jsonplaceholder.typicode.com/posts/1`, postFetcher)

  const commentsFetcher = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts/1/comments').then(
        (response) => response.json()
      )

      return response
    } catch (error) {
      console.error(error)
      return null
    }
  }

  const { data: comments } = useSWR(
    `https://jsonplaceholder.typicode.com/todos/1/comments`,
    commentsFetcher
  )

  return (
    <>
      <p>タイトル</p>
      <p>{post && post.title}</p>

      {comments &&
        comments.map((item) => (
          <div key={item.id}>
            <p>name: {item.name}</p>
            <p>comment: {item.body}</p>
          </div>
        ))}
    </>
  )
}
export default Page

変更点は二つです。
一つ目はfetcerの関数名をpostFetchercommentsFetcherに変更しました。
こうすることで関数名が一意になり、the name `fetcher` is defined multiple timesというエラーが解消されます。

二つ目はこちらから

const { data } = useSWR(`https://jsonplaceholder.typicode.com/posts/1`, postFetcher)

こちらに変更してdataの変数名をオリジナルの変数名を命名したことです。

const { data: post } = useSWR(`https://jsonplaceholder.typicode.com/posts/1`, postFetcher)

このように修正することで2つのエラーが解消されてポストとコメントを出力することができるようになりました。

最後に

いかがでしたでしょうか?
思っていたよりも簡単に解決できたのではないかと思います。
意外と今回紹介したことに関する技術記事が少なかったので書くことにしてみました。
参考になったら嬉しいです。

今後もこのように意外とない技術記事について書いていこうと思いますので見ていただけると幸いです。

また、いいねとストックをしてもらえると執筆するモチベになるのでしていただけると嬉しいです!

最後まで読んでいただきありがとうございました!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?