Suspense / React
Suspenseは、コンポーネントが「まだ表示できる状態にない(データを読み込み中など)」ときに、代わりにローディング画面(フォールバック)を自動で表示してくれる機能
今まで
code:tsx
function UserProfile() {
const { data, loading } = useFetchUser();
// コンポーネントごとにこれが必須だった
if (loading) return <Spinner />;
return <div>{data.name}</div>;
}
Suspense
code:tsx
// 呼び出し側で包むだけ!
<Suspense fallback={<Spinner />}>
<UserProfile />
</Suspense>
何が嬉しいのか
画面の中に、データ通信を行うパーツが5個も10個もある場合
普通に実装するとそこらじゅうにローディングが出る
Suspenseを使うと
code:tsx
// これだけで、3つの通信が「全部終わるまで」大きなスピナー1個でスマートに待てる
<Suspense fallback={<BigSpinner />}>
<Navbar />
<UserProfile />
<PostList />
</Suspense>
とはいえ、親コンポーネントにuseStateを使って、個々のローディングのStateを管理すればいいだけではある
code:tsx
// 親コンポーネントでまとめて管理するイメージ
function Parent() {
const loading, setLoading = useState(true);
const user, setUser = useState(null);
const posts, setPosts = useState([]);
useEffect(() => {
// Promise.all などで同時に通信して、全部終わったら loading を false にする
Promise.all(fetchUser(), fetchPosts()).then((userData, postsData) => {
setUser(userData);
setPosts(postsData);
setLoading(false);
});
}, []);
if (loading) return <BigSpinner />;
return (
<div>
<UserProfile data={user} />
<PostList data={posts} />
</div>
);
}
冗長ではあるが
#tech #React