You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何等待所有图片加载完成后隐藏Loading组件?

React 图片批量加载优化方案

问题场景

我使用ReactJS开发页面,现有简化代码如下:

const Page = () => {
    const [isLoading, setIsLoading] = useState(true);
    
    return (
        <Loading isLoading={isLoading} >
            <img src='https://example.com/img1' alt='image' />
            <img src='https://example.com/img2' alt='image' />
            <img src='https://example.com/img3' alt='image' />
            <img src='https://example.com/img4' alt='image' />
            <img src='https://example.com/img5' alt='image' />
            <img src='https://example.com/img6' alt='image' />
            <img src='https://example.com/img7' alt='image' />
        </Loading>
    )
}

当前问题

图片会逐个渐进式显示,视觉效果差,加载过程中页面布局频繁跳动。

期望效果

页面打开时先展示<Loading>组件(isLoading设为true),待所有图片加载完成后,再将isLoading设为false,隐藏加载组件,一次性展示所有图片。

解决方案

通过预加载所有图片并监听加载状态,全部完成后切换isLoading状态,具体实现代码如下:

import { useState, useEffect } from 'react';

const Page = () => {
    const [isLoading, setIsLoading] = useState(true);
    // 统一管理图片地址数组
    const imageUrls = [
        'https://example.com/img1',
        'https://example.com/img2',
        'https://example.com/img3',
        'https://example.com/img4',
        'https://example.com/img5',
        'https://example.com/img6',
        'https://example.com/img7'
    ];

    useEffect(() => {
        let loadedCount = 0;
        const totalImages = imageUrls.length;

        // 遍历预加载所有图片
        imageUrls.forEach(url => {
            const img = new Image();
            img.src = url;
            
            // 图片加载成功回调
            img.onload = () => {
                loadedCount++;
                checkAllLoaded();
            };
            
            // 图片加载失败也计入完成,避免加载状态卡死
            img.onerror = () => {
                loadedCount++;
                checkAllLoaded();
            };
        });

        // 检查是否所有图片已加载完成
        const checkAllLoaded = () => {
            if (loadedCount === totalImages) {
                setIsLoading(false);
            }
        };

        // 组件卸载时清理计数,避免状态更新报错
        return () => {
            loadedCount = totalImages;
        };
    }, [imageUrls]);

    return (
        <Loading isLoading={isLoading} >
            {imageUrls.map((url, index) => (
                <img key={index} src={url} alt={`image ${index + 1}`} />
            ))}
        </Loading>
    )
}

方案说明

  • 将图片地址存入数组,既方便预加载遍历,也能通过map渲染图片元素,减少重复代码。
  • 利用useEffect在组件挂载时启动预加载,通过原生Image对象加载图片,同时监听成功和失败事件,确保所有图片状态都被统计。
  • 每完成一张图片加载(无论成功失败)就计数,当计数等于图片总数时,切换加载状态,一次性展示所有内容。
  • 添加清理函数,防止组件卸载后触发状态更新,避免内存泄漏。

内容的提问来源于stack exchange,提问作者arrmani88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:01:06