【React】Suspenseとfetchを使ったときのエラー

プログラミング
スポンサーリンク

起こった問題

React18にあるローディングを簡単にする機能、Suspenseにおいて、よくわからない事象が起きた。
簡潔に言うと、SSRとCSRで生成されたDOM情報が異なるというエラーだ。

Error: Text content does not match server-rendered HTML
Alt text

Error: There was an error while hydrating this Suspense boundary. Switched to client rendering.
Alt text

なぜ起こるのか

fetchなど、APIを用いてデータを取得している画面でデータを更新、リロードを行うと、SSRはキャッシュがあるためか、はたまたバグか、データ更新前の情報を保持している。
その後、CSRはAPIで最新のデータを取得しレンダリングする。
その結果、更新前と更新後で情報が異なるため、レンダリングされた情報が異なるとエラーになる。

解決方法

remix-utilsモジュールを利用しました。
この中にある、ClientOnlyを用いると、レンダリングをクライアントだけにできます。
使い方はシンプルで、SuspenseのかわりにClientOnlyタグに変更し、子要素を{}でreturnするように修正します。

$ npm i remix-utils
import { ClientOnly } from "remix-utils/client-only";

{中略}
    // Suspense → ClientOnly    
    // <Suspense fallback={<Loading />}>{child}</Suspense>
    <ClientOnly fallback={<Loading />}>{() => <>{child}</>}</ClientOnly>

まとめ

  • React18のSuspenseとfetchを使用した際に起こるエラーと解決方法について
  • ClientOnlyをつかって、レンダリングをCSRのみに
  • エラーはReact側のバグの可能性があるため、アップデートで治るかも

参考

How to troubleshoot hydrating errors? · remix-run/remix · Discussion #5648
Hello, My app is spitting hydration errors every second. I have 2.5K errors per hour. These are the error types: There w...

コメント

タイトルとURLをコピーしました