「フロントエンドLT会 - vol.8」で発表したスライドです。 https://rakus.connpass.com/event/255095/
ReactのSuspenseを使った非同期処理のエラーハンドリングフロントエンドLT会 - vol.8 2022.09.08(木)
View Slide
自己紹介● taro( @taroro_tarotaro)● Shelfyで建設SaaSを作ってるエンジニア(あと少しで2年)● React, Spring, Django, AWS, k8s
はじめに
Suspenseとは
SuspenseとはComponentをLoading状態にできる機能
SuspenseとはComponentをLoading状態にできる機能これまで
SuspenseとはComponentをLoading状態にできる機能これまで Suspenseを使うと
SuspenseとはComponentをLoading状態にできる機能これまで Suspenseを使うと取得されている前提で宣言的に書ける!
Suspenseとは宣言的UIフレームワーク・ライブラリのSuspenseの提供状況● React→提供済● Vue→実験的機能として提供● Solid→提供済● Svelte→未提供
Suspenseとは宣言的UIフレームワーク・ライブラリのSuspenseの提供状況● React→提供済● Vue→実験的機能として提供● Solid→提供済● Svelte→未提供→Suspenseは宣言的UIの標準になっていくと考えられる機能→React以外の使い手の方にも、参考になれば嬉しいです🙂
今までの非同期処理のエラーハンドリング
PromiseチェーンでのエラーハンドリングFetch API axios
データ取得ライブラリ(swr)でエラーハンドリングIn Hooks or Component
データ取得ライブラリ(swr)でエラーハンドリングIn Hooks or Component swr内ではtry-catchしているhttps://github.com/vercel/swr/blob/main/core/use-swr.ts#L307
Suspenseを使ってみる
Suspenseを使ってみるSuspense導入前
Suspenseを使ってみるSuspense導入前 Suspense導入後
Suspenseを使ってみるエラーが発生(ホワイトアウト) Suspense導入後
Suspenseを使ってみるエラーが発生(ホワイトアウト)→swrがエラーをcatchしていないSuspense導入後
Suspenseを使ってみるエラーが発生(ホワイトアウト)→swrがエラーをcatchしていない→なぜか?Suspense導入後
ReactのSuspenseの仕組み
ReactのSuspenseの仕組みSuspense内のComponentをrender
ReactのSuspenseの仕組みrender中にpromiseがthrowされたら、直近のSuspenseがcatch
ReactのSuspenseの仕組みpromiseがpendingの時は、Suspense内にfallbackをrender
ReactのSuspenseの仕組みsettled(fulfilled or rejected)されたら再度render
ReactのSuspenseの仕組みrenderに成功したら描画される!(再度promiseがthrowされたらループ)
ReactのSuspenseの仕組みswrも内部でpromiseをthrowhttps://github.com/vercel/swr/blob/main/core/use-swr.ts#L597
ReactのSuspenseの仕組みswrも内部でpromiseをthrowpromiseを扱うのはsuspenseなので、swrはエラーをcatchしていない
じゃあどうするか?
じゃあどうするか?SWRの公式ドキュメントhttps://swr.vercel.app/docs/suspense
Error Boundaryエラーハンドリング用ライフサイクルメソッドを使ったComponent (V16~)● getDerivedStateFromError● ComponentDidCatch子Componentツリーで発生したJavaScriptのエラーをcatch● fallbackを表示● エラーを記録https://reactjs.org/docs/error-boundaries.html
Error Boundaryhttps://reactjs.org/docs/error-boundaries.htmlError Boundaryって、非同期処理に使えなかった気がする。。。
Error Boundaryって、非同期処理に使えなかった気がする。。。Error Boundaryhttps://reactjs.org/docs/error-boundaries.html
Error Boundaryって、非同期処理に使えなかった気がする。。。Error Boundary→React内部で発生するエラーしかcatchできないhttps://reactjs.org/docs/error-boundaries.html
Error Boundaryhttps://reactjs.org/docs/error-boundaries.htmlError Boundaryって、非同期処理に使えなかった気がする。。。→React内部で発生するエラーしかcatchできない→Suspenseだと非同期処理もReact内部で制御されるからcatchできる
より宣言的に書けるようになった!● ローディング→Suspense● エラー→ErrorBoundaryError Boundary使う
エラーハンドリングを分岐したい
catchしたエラーの中身を見て、分岐してあげればOK!エラーハンドリングを分岐したい
Error Boundaryを分けたい時は、errorをre-throwすればOK!エラーハンドリングを分岐したい
Error Boundaryを分けたい時は、errorをre-throwすればOK!re-throwしないError Boundaryが、エントリーポイントにあると安心 🙂ErrorBoundary自体、low-levelのAPIで構築されているので柔軟性は高いエラーハンドリングを分岐したい
さいごに
さいごにError BoundaryとSuspenseめっちゃ似てる
Error BoundaryとSuspenseめっちゃ似てるSuspense=PromiseのみをcatchするBoundaryさいごにhttps://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberThrow.new.js#L312
Error BoundaryとSuspenseめっちゃ似てるSuspense=PromiseのみをcatchするBoundary宣言的にUIを構築するには、その対象をReactの管理下に置く必要がある● state: 宣言的に書ける● ref: 宣言的に書けないさいごにhttps://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberThrow.new.js#L312
Error BoundaryとSuspenseめっちゃ似てるSuspense=PromiseのみをcatchするBoundary宣言的にUIを構築するには、その対象をReactの管理下に置く必要がある● state: 宣言的に書ける● ref: 宣言的に書けない宣言的に非同期処理扱うために、PromiseをReactにthrowしているさいごにhttps://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberThrow.new.js#L312
Error BoundaryとSuspenseめっちゃ似てるSuspense=PromiseのみをcatchするBoundary宣言的にUIを構築するには、その対象をReactの管理下に置く必要がある● state: 宣言的に書ける● ref: 宣言的に書けない宣言的に非同期処理扱うために、PromiseをReactにthrowしているPromiseをthrowすることへの違和感が減る (?)さいごにhttps://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberThrow.new.js#L312
まとめ
まとめ● Suspenseを使うと非同期処理が宣言的に書ける● Suspenseだと非同期処理のエラーもError Boundaryで宣言的にエラーハンドリングできる● SuspenseはPromiseのみをcatchするBoundary
まとめ● Suspenseを使うと非同期処理が宣言的に書ける● Suspenseだと非同期処理のエラーもError Boundaryで宣言的にエラーハンドリングできる● SuspenseはPromiseのみをcatchするBoundarySuspenseとError Boundaryでより宣言的なUI開発を!
ありがとうございました!