トップ/記事一覧

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
ReactDOMServer does not yet support Suspense

これは、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;

useRecoilValueLoadableLoadable オブジェクトを返却します。Loadable オブジェクトは、3つのいずれかで、Switch 文にある通りですが、fetch 中、fetch 成功、fetch 失敗のいずれかの状態を表すオブジェクトです。(型定義部分のスクリーンショットを添付)

Loadble オブジェクトの型定義
Loadble オブジェクトの型定義

Loadable.state で状態が取れるので、状態によってコンポーネントの出し分けを自前で実装すれば良いというわけですね。ちょっとハマったのでメモでした。