Suspense
https://youtu.be/FZ0cG47msEk?t=411
目的はReactでデータフェッチの取り扱いを明確にすること
Reactでデータフェッチして表示するようなコンポーネントを書くとき
useEffectでやると上から下にロジックがいかないので分かりづらいし、バグを生みやすい
そこで普通useSWRなどを使って上から下に読めるように書く code:jsx
function List({pageID}) {
if (isLoading) {
return <Spinner />
}
return itemspageId.map(item => <li>{item}</li>
);
}
このコードを読んでも改善できると思う人は少ない
JSを使っていると非同期がデフォルトだから、対処するのに慣れている
Reactチームは「これはもっと改善できる」と思った
上のコードは、2つの概念が混じってる
1. data feching(items)
2. データロードの状態管理(isLoadingで処理を分けてる)
これらが混ざっていることで、2つの問題がある
任意のコンポーネント内で、データ取得を増やしたら、ロードの状態管理も考えなければならない
ロード中に何を返すのか考えて決める必要がある。面倒
それをどこで返すのかも考えて決める必要がある
そのコンポーネント内で返す?
親のコンポーネントに渡すなら(React単体なら)親に子コンポーネントの APIの通信状態をもつstateを用意する必要がある
ロード状態の表示を変更したい場合、データフェッチのコードを修正する必要がある
データをロードするコンポーネントが複数作った。ロード状態を1つにまとめたい
2つのクエリを親コンポーネントに持っていく必要がある
Reduxで管理すればこの変更は不要だkadoyau.icon
SuspenseとReduxって役割一部同じなんじゃ?
Reduxでやっていたロードの状態管理をSuspenceに移した方がいいかもしれない
これをSuspenceで分割して解決する
ロードのステートをJSXの中に書く
code:jsx
<Suspence fallback={<Spinner />}> // Listが準備されてなかったらSpinnerを表示する
<List pageId={pageId) />
</Suspence>
最も直近のSuspenceにhook upされる
この仕組みを使うと、SSRもできる
仮のHTMLをロードしておいて、データフェッチしたら差し替える
今後他のライブラリも統合できるようにAPIを拡充する
2021-09-14時点でexperimental
hydration前の要素をユーザーがクリックするとイベントを記録し、優先的にhydrationしてイベントをリプレイ