- 创建一个状态管理钩子
import { useState, useCallback } from "react";
const usePageInitializer = () => {
const [state, setState] = useState({
loading: true,
userData: null,
userOrders: null,
notifications: null,
errors: {
userDataError: null,
userOrdersError: null,
notificationsError: null,
},
isAllSettled: false,
});
const init = useCallback(async () => {
// 开始加载时重置状态
setState({
loading: true,
userData: null,
userOrders: null,
notifications: null,
errors: {
userDataError: null,
userOrdersError: null,
notificationsError: null,
},
isAllSettled: false,
});
try {
const [userDataResult, userOrdersResult, notificationsResult] =
await Promise.allSettled([
fetchUserData(),
fetchUserOrders(),
fetchNotifications(),
]);
// 正确处理状态更新
setState({
loading: false,
userData: userDataResult.status === 'fulfilled' ? userDataResult.value : null,
userOrders: userOrdersResult.status === 'fulfilled' ? userOrdersResult.value : null,
notifications: notificationsResult.status === 'fulfilled' ? notificationsResult.value : null,
errors: {
userDataError: userDataResult.status === 'rejected' ? userDataResult.reason : null,
userOrdersError: userOrdersResult.status === 'rejected' ? userOrdersResult.reason : null,
notificationsError: notificationsResult.status === 'rejected' ? notificationsResult.reason : null,
},
isAllSettled: true,
});
} catch (error) {
setState((prev) => ({
...prev,
loading: false,
isAllSettled: true,
}));
}
}, []);
return { ...state, init };
};
在组件(如HomePage)中使用
const HomePage = () => {
const { loading, userData, userOrders, notifications, errors, isAllSettled, init } = usePageInitializer();
useEffect(() => {
init();
}, [init]);
if (loading) {
return <div>页面初始化中...</div>;
}
return (
<div>
<Header userData={userData} error={errors.userDataError} />
<OrderList orders={userOrders} error={errors.userOrdersError} />
<NotificationCenter notifications={notifications} error={errors.notificationsError} />
{isAllSettled && !loading && (
<p>所有请求已完成(可能存在部分失败)</p>
)}
</div>
);
};
子组件示例 - Header
const Header = ({ userData, error }) => {
if (error) {
return (
<header>
<h1>首页</h1>
<p>用户信息加载失败: {error.message}</p>
</header>
);
}
if (!userData) {
return (
<header>
<h1>首页</h1>
<p>加载中...</p>
</header>
);
}
return (
<header>
<h1>欢迎回来, {userData.name}</h1>
<img src={userData.avatar} alt="用户头像" />
</header>
);
};