react-query3接口返回成功但图片未完全加载,如何实现全量加载后展示内容并显示统一加载动画
实现方案
核心逻辑:useQuery 的 success 状态仅代表Unsplash接口的元数据(包含图片URL的数组)请求完成,不代表真实图片资源加载完毕。你需要额外监听所有图片的加载完成事件,等全部加载完成后再隐藏加载动画、显示图片列表。
1. 修改 GetImages.js 组件
增加加载计数和全部加载完成的状态,把加载完成的回调传给Image组件,并且调整渲染逻辑,只要还没全部加载完成就显示居中的Spinner。
import React, { useState } from "react"; import { useQuery } from "react-query"; import Image from "./Image"; import Spinner from "react-bootstrap/Spinner"; const fetchImage = async () => { let config = { method: "GET", headers: { Authorization: "Client-ID ID", }, mode: "cors", cache: "default", }; const res = await fetch("https://api.unsplash.com/photos", config); return res.json(); }; const GetImages = () => { const { data, status } = useQuery("images", fetchImage); const [loadedCount, setLoadedCount] = useState(0); const [allImagesLoaded, setAllImagesLoaded] = useState(false); // 单张图片加载完成的回调 const handleImageLoad = () => { setLoadedCount(prev => { const newCount = prev + 1; // 加载数量等于图片总数时标记全部加载完成 if (newCount === data.length) { setAllImagesLoaded(true); } return newCount; }); }; // 接口请求中 或 图片未全部加载完成 都显示Spinner if (status === "loading" || (status === "success" && !allImagesLoaded)) { return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px" }}> <Spinner animation="border" role="status"> <span className="visually-hidden">Loading...</span> </Spinner> </div> ) } if (status === "error") return <div>Error</div>; return ( <div> {data.map((image) => <Image key={image.id} image={image} onLoad={handleImageLoad} />)} </div> ); }; export default GetImages;
2. 修改 Image.js 组件
接收父组件传来的onLoad回调,绑定到img标签的onLoad事件上:
const Image = ({ image, onLoad }) => { return ( <div className="card"> <img src={image.urls.raw} alt={image.alt_description} style={{ width: 100, height: "auto" }} onLoad={onLoad} // 可选:添加图片加载失败的回调,避免某张图加载失败一直卡Spinner onError={onLoad} /> </div> ); }; export default Image;
内容的提问来源于stack exchange,提问作者jeyremd
相关产品推荐
相关产品推荐

