Next.js v13 で遭遇したエラー達

エラー
クライエント側で use を使うと再レンダリングが何度も走ってしまう。
"use client"
import React, { use } from "react"
const getPlayer = async () => {
const res = await fetch("http://localhost:3000/api/mock/player")
if (!res.ok) {
throw new Error("プレイヤーの取得に失敗しました。")
}
return res.json()
}
// このコンポーネントが無限に再レンダリングされる
const Player = () => {
console.log("レンダリング(`・ω・´)")
const data = use(getPlayer())
return (
<div>
<p>{data?.player.name}</p>
<p>{data?.player.bio}</p>
</div>
)
}
const PlayerPage = () => {
return (
<div>
<h1>プレイヤーのページ</h1>
<Player />
</div>
)
}
export default PlayerPage
原因
use にはキャッシュの責務がない事が原因で、Promise 解決 -> レンダリング -> Promise 解決のループが無限に発生してしまうらしい。
解決策
cache という関数の実行結果をメモ化する hook を利用する事で、引数が変わるまで getPlayer が同じ promise を返し、再レンダリングを抑止できる。
...
import { use , cache } from "React"
const getPlayer = cache(async () => {
const res = await fetch("http://localhost:3000/api/mock/player")
if (!res.ok) {
throw new Error("プレイヤーの取得に失敗しました。")
}
return res.json()
})
...
参考にさせていただいた記事

エラー
use と cache と Suspense を組み合わせて使うと Error: Not implemented. が表示される。
"use client"
...
const PlayerPage = () => {
return (
<div>
<h1>プレイヤーのページ</h1>
+ <Suspense fallback={<div>loading!!</div>}>
<Player />
+ </Suspense>
</div>
)
}
...
原因
cache の一部の機能 (getCacheForType) がまだ未実装な為エラーが起きるらしい。
Suspense を使った際に呼びされる?
Hi friends! Really appreciate all the investigation and discussion here. I spoke with the team about this and >it looks like, perhaps as expected, we don't have this functionality quite finished yet. We tried to clarify in >the docs that fetch is not yet supported in client components - the recommendation right now is to fetch >data in server components.
Next.js 公式的には fetch はクライアントコンポネントに未対応のため、サーバーコンポーネントでのデータの取得を推奨しているらしい。
fetch is currently not supported in Client Components and may trigger multiple re-renders. For now, if you >need to fetch data in a Client Component, we recommend using a third-party library such as SWR or React >Query.
beta next.js ドキュメントにも記載があり、クライアントコンポーネントで fetch したい場合は、SWR か React Query を使う事を推奨しているらしい。
解決策
データの取得はなるべく、サーバー側で行って、use, cache, fetch の代わりに SWR, axios? を使うほうが良さそう?
Suspense を使わなければ、エラーは起きなくなった。
参考にさせていただいた記事