generated at
Error BoundaryとSuspense

責務が異なる
Error Boundaryは、errorが生じた際に
壊れたUIを表示するのではなく、「エラーが起きました」のような代替UIを表示する
React.Suspenseは、データのfetch中に
壊れたUIを表示するのではなく、「loading...」のような代替UIを表示する



何が似ているか
Componentを書く際に、errorが起きた時や、fetch中の表示を考えなくて済む
従来はこんな感じに書いていた
ts
// プロフィールを表示することが責務であるComponent const Profile = () => { const { value, isError, isLoading } = useFetch(); if(isError) { return (..) } if(isLoading) { return (..) } return <div>{value}</div> }
Error BoundaryやSuspenceを使うことで、errorやloadingを気にする必要がない
ts
// プロフィールを表示することが責務であるComponent const Profile = () => { const { value } = useFetch(); // この辺でerror処理を書かなくて良い // この辺でloading時の処理を書かなくて良い return <div>{value}</div> }
「プロフィールを表示する」という責務に則ったことだけを書いてれば良い
では、実際にerrorが起きた時や、fetch中にどうするか?
それ専用のComopnentを用意する
error時の処理は、 <ErrorBoundary /> のようなComponentを作って
「errorが起きた時に何かを表示する」という責務のみを全うする
fetch時も、 <Loading /> のようなComponentを作って、
「良い感じのloadingを表示する」という責務のみを全うする
これを使いたいまとまりごとにComponentで囲うだけ
ts
<ErrorBoundary> <Suspense fallback={<Loading/>}> <Profile/> </Suspense> </ErrorBoundary>
Profileで待ち時間が生じた場合は <Loading/> が表示され
Profileでerrorが生じた場合は、 <ErrorBoundary/> 内のerror messageが表示される
<Profile/> のComponentの定義内では、errorやloadingのことを気にしなくていい
より宣言的になった、と言える



囲う粒度は自由で、project全体を1つ囲うだけでも良いし、刻んでも良い
捕捉したいまとまりを囲んで使う
ts
<A> <B/> <ErrorBoundary1> <C/> <ErrorBoundary2> <D/> <E/> </ErrorBoundary2> <ErrorBoundary3> <F /> </ErrorBoundary3> </ErrorBoundary1> <A/>
この場合、Dでerroが生じた場合は、DとEの両方が、代替物に置き換わる
そうすれば例えばfooterでerrorが起きた時に、contents部分には何も影響がないとか、
YouTubeのような動画サイトを作って表示する時に、
動画部分を1番優先的に表示して、
関連動画とかは後で読み込む
のようなことが簡単に書ける


両者ともView上の try/catch のようなイメージ
<Profile/> のComponentの中で、errorやloadingが生じたことに対してhandlingしない
親(以上のなにか)がhandlingする
親かもしれないし、親の親かもしれない
直近でhandlingしている親のとこまで飛ぶ
内部で throw した時に、直近の try まで吹っ飛んでhandlingされる try/catch と似ている


Suspenseには
コレは両方とも待ち時間の話をしていて、
「何の待ち時間か」の部分が異なるだけ