はじめに
前回までの記事の続きです。React18の実装前の場合はどのように表現する必要があるのかを記載していこうと思います!
成果物
src/SuspendUserOld.tsx
import React, { Suspense, useState, useEffect, lazy } from "react";
// 遅延ロードするコンポーネント
const UserList = lazy(() => import("./UserList")); // default exportでないと表示ができません。
// API通信関数
const getUserData = async () => {
await new Promise((resolve) => setTimeout(resolve, 5000));
const res = await fetch("https://jsonplaceholder.typicode.com/users");
if (!res.ok) {
throw new Error("Failed to fetch data");
}
return res.json();
};
// メインコンポーネント
export const SuspendUserOld = () => {
const [userData, setUserData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
// API通信を行う
const fetchData = async () => {
try {
const data = await getUserData();
setUserData(data);
setLoading(false);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
fetchData();
}, []);
// ローディング中のUI表示
if (loading) {
return <div>Data fetching Loading...</div>;
}
// エラーが発生した場合の表示
if (error) {
return <div>Error: {error}</div>;
}
return (
<Suspense fallback={<FallbackUI />}>
<UserList userData={userData} />
</Suspense>
);
};
export const FallbackUI = () => {
return (
<div>
<p>Fallback Loading...</p>
</div>
);
};
UserList.tsx
import React from "react";
// `UserList` コンポーネント
const UserList = ({ userData }: { userData: any }) => {
return (
<ul>
{userData.map((user: any) => (
<li key={user.id}>
{user.name} ({user.email})
</li>
))}
</ul>
);
};
export default UserList; //lagyでimportする場合、デフォルトエクスポートでないとimportできません。
おわりに
Suspenseだけで表現できない分、ちょっと実装が面倒な箇所がありますね!
React18のSuspenseは優秀ですね!