トップ/記事一覧
Next.js で React.Suspense を使った時の ReactDOMServer does not yet support Suspense エラーが出た
📆2021/01/04(最終更新日:2021/01/16)🔖 Next.js
⚠ この記事は最終更新日から1年以上が経過しています。内容が古い箇所がある可能性があるためご注意ください。
Recoil の試し切りをしていたところ、非同期通信のところでハマったのでメモ。
JavaScript
function ResultsSection() { return ( <React.Suspense fallback={<div>Loading...</div>}> <QueryResults /> </React.Suspense> ); } export default ResultsSection;
(QueryResults は非同期通信で取得した値を描画するコンポーネントです)上記のようなコードで、fetch 中は Loading... というコンポーネントを表示したかったのですが、以下のように ReactDOMServer does not yet support Suspense というエラーが出てしまいました。
![ReactDOMServer does not yet support Suspense](/_next/image?url=%2FblogImages%2F03a5a3bc-ab45-4eb9-a692-14a64c4834d6.png&w=1920&q=75)
これは、React.Suspense がまだ SSR に対応してないことによるエラーでした。今回は、Recoil の fetch 部分で React.Suspense が使用したかったのですが、調べたところ以下の Issue で全く同じことが議論されており、対応策として、useRecoilValueLoadable を使えば良いとのことでした。
https://github.com/facebookexperimental/Recoil/issues/722
結論、React.Suspense を使用せず、以下のようなコードにすれば OK 。
JavaScript
function QueryResults() { const queryResults = useRecoilValueLoadable(myQuery); switch (queryResults.state) { case "hasValue": return <div>{queryResults.contents.id}</div>; case "loading": return <div>Loading...</div>; case "hasError": throw queryResults.contents; } } function ResultsSection() { return <QueryResults />; } export default ResultsSection;
useRecoilValueLoadable は Loadable オブジェクトを返却します。Loadable オブジェクトは、3つのいずれかで、Switch 文にある通りですが、fetch 中、fetch 成功、fetch 失敗のいずれかの状態を表すオブジェクトです。(型定義部分のスクリーンショットを添付)
![Loadble オブジェクトの型定義](/_next/image?url=%2FblogImages%2F6f918916-2f88-4a8c-a265-055b89d31eca.png&w=1920&q=75)
Loadable.state で状態が取れるので、状態によってコンポーネントの出し分けを自前で実装すれば良いというわけですね。ちょっとハマったのでメモでした。