今回やりたいこと
今回やりたいことはタイトルにもある通り、同一ファイル内で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
という関数名が複数回定義されているため先ほどのエラーが出るのです。
ではどうやってこのエラーを解決するのか?
解決方法は簡単です。data
とfecter
にオリジナルの名前をつけてあげればいいのです。
言葉でまず説明するよりもコードを見たほうが早いと思うのでコードを見てみましょう。
以下が期待通りに動くコードになります。
'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
の関数名をpostFetcher
とcommentsFetcher
に変更しました。
こうすることで関数名が一意になり、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つのエラーが解消されてポストとコメントを出力することができるようになりました。
最後に
いかがでしたでしょうか?
思っていたよりも簡単に解決できたのではないかと思います。
意外と今回紹介したことに関する技術記事が少なかったので書くことにしてみました。
参考になったら嬉しいです。
今後もこのように意外とない技術記事について書いていこうと思いますので見ていただけると幸いです。
また、いいねとストックをしてもらえると執筆するモチベになるのでしていただけると嬉しいです!
最後まで読んでいただきありがとうございました!