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

React中setListImg无法接收Blob值,useState更新延迟致报错

问题解决思路与代码修复

核心问题分析

  1. useState异步更新特性:setListImg是异步操作,调用后listImg不会立刻更新,组件首次渲染时listImg仍为空数组,直接访问listImg[fun.cod-1]会得到undefined,触发URL.createObjectURL报错。
  2. 索引依赖不可靠:通过fun.cod-1作为数组索引关联图片,若listFunc顺序变动,会导致图片与对应项不匹配。
  3. 未处理加载状态:图片加载完成前直接渲染,无 fallback 逻辑,引发报错。

修复后的代码

import { useEffect, useState, useRef } from 'react';

// 组件内部逻辑
const [listImg, setListImg] = useState([]);
const [status, setStatus] = useState('carregando');
const urlRefs = useRef({}); // 存储创建的URL,用于后续内存清理

useEffect(() => {
    if (listFunc.length === 0) return;

    const imgfetch = async () => {
        setStatus('carregando');
        // 返回包含cod和blob的对象,避免依赖数组索引匹配
        const imgFiles = await Promise.all(
            listFunc.map(async (fun) => {
                const resp = await fetch(`${url}imagem/${fun.cod}-func`, { method: 'GET' });
                const blob = await resp.blob();
                return { cod: fun.cod, blob };
            })
        );
        setListImg(imgFiles);
        setStatus('ocioso');
    };

    imgfetch();

    // 清理内存:组件卸载或listFunc变化时,销毁已创建的URL
    return () => {
        Object.values(urlRefs.current).forEach(url => URL.revokeObjectURL(url));
        urlRefs.current = {};
    };
}, [listFunc, url]); // 补充url到依赖数组,符合React Hooks规则

return (
    <div>
        {status === 'carregando' ? (
            <p>Carregando imagens...</p>
        ) : (
            listFunc.map((fun) => {
                // 通过cod精准匹配对应的blob数据
                const imgData = listImg.find(item => item.cod === fun.cod);
                // 仅当blob存在时才创建URL
                const imgUrl = imgData?.blob ? URL.createObjectURL(imgData.blob) : null;
                // 将URL存入ref,方便后续清理
                if (imgUrl) urlRefs.current[fun.cod] = imgUrl;

                return (
                    <div style={{ textAlign: "justify", padding: '20px 100px 0px 100px' }} key={fun.cod}>
                        <div style={{ display: "flex" }}>
                            {/* 图片加载失败或未就绪时显示占位图 */}
                            <img 
                                src={imgUrl || '你的占位图地址'} 
                                alt={fun.nome}
                                onError={(e) => e.target.src = '你的占位图地址'}
                            />
                            <div style={{ paddingLeft: '20px' }}>
                                <h2>{fun.nome}</h2>
                                <p>{fun.desc}</p>
                            </div>
                        </div>
                        <hr />
                    </div>
                )
            })
        )}
    </div>
);

关键改动说明

  • 关联cod与Blob:放弃数组索引匹配,改用cod字段精准关联图片数据,避免顺序变动导致的匹配错误。
  • 加载状态处理:添加加载中提示,避免图片未加载完成时直接渲染引发报错。
  • 空值安全判断:使用可选链?.判断blob是否存在,仅在有效时调用URL.createObjectURL。
  • 内存泄漏防护:通过useRef存储创建的URL,在组件卸载或依赖变化时主动释放内存。
  • 完善依赖数组:将url补充到useEffect依赖中,符合React Hooks的规范要求。

内容的提问来源于stack exchange,提问作者João

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:20:27