接口太多导致页面加载慢,能合并请求吗?

一统乐 阅读 16

我们首页要同时拉用户信息、订单列表和系统通知,现在是三个独立的 useEffect 去请求,感觉太慢了。试过用 Promise.all 但不知道怎么在 React 里优雅地处理状态更新,代码一写就乱。

有没有推荐的合并方式?比如封装成一个 hook 或者用 RTK Query 这类工具?

useEffect(() => {
  fetch('/api/user').then(res => setUser(res.data));
}, []);

useEffect(() => {
  fetch('/api/orders').then(res => setOrders(res.data));
}, []);

useEffect(() => {
  fetch('/api/notifications').then(res => setNotis(res.data));
}, []);
我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
诸葛春豪
试试这个方法,先封装一个统一的 hook 来处理多请求合并,避免重复写 useEffect,也方便后续扩展或缓存:

function useHomeData() {
const [user, setUser] = useState(null);
const [orders, setOrders] = useState([]);
const [notifications, setNotifications] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchAll = async () => {
try {
setLoading(true);
const [userRes, ordersRes, notiRes] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/notifications').then(r => r.json())
]);
setUser(userRes.data);
setOrders(ordersRes.data);
setNotifications(notiRes.data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchAll();
}, []);

return { user, orders, notifications, loading, error };
}


然后在组件里直接用:

const { user, orders, notifications, loading } = useHomeData();
if (loading) return <LoadingSpinner />;
// 渲染逻辑...


如果项目里到处都要这种组合请求,可以再抽象一层通用 hook,比如:

function useCombinedQueries(queries) {
const [data, setData] = useState({});
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchAll = async () => {
try {
setLoading(true);
const results = await Promise.all(
Object.entries(queries).map(async ([key, fn]) => {
const res = await fn();
return [key, res];
})
);
setData(Object.fromEntries(results));
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchAll();
}, [Object.keys(queries)]);

return { data, loading, error };
}


用法:

const { data, loading } = useCombinedQueries({
user: () => fetch('/api/user').then(r => r.json()),
orders: () => fetch('/api/orders').then(r => r.json()),
notifications: () => fetch('/api/notifications').then(r => r.json())
});


RTK Query 也行,但如果你只是想简单合并请求,上面这种轻量方案更直接,不用引入新依赖,改起来也方便。
点赞 7
2026-02-25 16:00