🌟
useSWRでデータフェッチするコンポーネントでSusponseを使うとエラーが出る
Next.jsでuseSWRでデータフェッチするコンポーネントでSusponseを使うと下記のエラーが出ました。
Error: Fallback data is required when using suspense in SSR.
サーバーサイドレンダリング(SSR)を行う際に、useSWRを使うと発生するエラーで、Suspenseがデータを待っている間に表示するフォールバックデータが必要であるためです。
回避策1. SSRしないようにする
SSR時に発生するエラーなのでコンポーネントをSSRすれば回避できます。
dynamic関数を使ってコンポーネントをインポートする際にssr
オプションをfalse指定すればSSRされません。
import dynamic from 'next/dynamic';
import React, { Suspense } from 'react';
const DataComponent = dynamic(() => import('./DataComponent'), {
ssr: false
});
export default function Page() {
return <div>
<Suspense fallback={<div>Loading...</div>}>
<DataComponent />
</Suspense>
</div>
}
回避策2. useSWRでフォールバックデータを渡す
useSWRのドキュメントでは下記のように記載されています。
サスペンスモードをサーバサイド(Next.js によるプリレンダリングを含む)で使う場合、fallbackData や fallback により初期データが提供されている必要があります。
このような感じでフォールバックデータをサーバサイドから渡してやるとOK
export async function getStaticProps () {
// `getStaticProps` はサーバーサイドで実行されます
const article = await getArticleFromAPI()
return {
props: {
fallback: {
'/api/article': article
}
}
}
}
function Article() {
// `data` は `fallback` 内にあるため常に利用可能です
const { data } = useSWR('/api/article', fetcher, {
suspense: true,
fallbackData: {}
})
return <h1>{data.title}</h1>
}
export default function Page({ fallback }) {
// `SWRConfig` 内の SWR フックはそれらの値を使用します
return (
<SWRConfig value={{ fallback }}>
<Article />
</SWRConfig>
)
}
またはuseSWRに渡す方法でも良いです。
const { data } = useSWR('/api/article', fetcher, {
suspense: true,
fallbackData: {}
})
しかし2だとSuspenseのfallbackが使えない…
fallbackDataの方が優先されてしまい肝心のSuspenseのfallbackが使えません。これは致命的です。
なので、1の方法で回避するのが良いでしょう。
下記の記事に詳しく説明されています。
Discussion