React中使用setState无法重置Blob数组?照片上传异常求助
问题分析与解决方案
你的核心问题源于React状态更新的异步特性,以及闭包导致的旧状态捕获,具体问题点:
setBlobs是异步操作,直接用[...blobs, ...]会捕获闭包中的旧状态,连续拍摄时会丢失之前的更新checkLength在fetch请求完成前就被调用,此时blobs还未更新,判断逻辑完全基于旧值- 判断条件
>=2不符合「每3张上传」的需求,逻辑匹配错误
修复后的代码
import { useState, useEffect } from 'react'; // 组件内部代码 const [blobs, setBlobs] = useState([]); const capturePhoto = async () => { const photo = await camera.current.takePhoto(); try { const res = await fetch(photo.path); // 使用函数式更新,确保基于最新状态添加新blob setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]); } catch (err) { console.log('err', err); } }; // 监听blobs状态变化,达到3张时执行上传与重置 useEffect(() => { const handleBatchUpload = async () => { if (blobs.length === 3) { const datestring = new Date().toLocaleString('de-DE'); // 等待所有上传完成后再重置状态,避免数据丢失 await Promise.all( blobs.map((blob, index) => uploadFile(blob, `${datestring}/${index + 1}.jpg`)) ); setBlobs([]); sendNotification('Photos uploaded'); toggleDialog(); } }; handleBatchUpload(); }, [blobs]); // 依赖blobs,每次状态变更都触发检查
关键修改说明
- 函数式状态更新:
setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]),确保每次更新都基于最新的状态值,彻底解决闭包导致的状态覆盖问题。 - useEffect监听状态:将上传逻辑移至
useEffect中,当blobs数组长度达到3时自动触发操作,保证判断的是最新的状态长度。 - 等待全部上传完成:用
Promise.all等待所有上传请求结束后再重置状态,避免上传未完成就清空数组引发的异常。 - 修正判断条件:改为
blobs.length === 3,严格匹配「每积累3张就上传」的需求。
内容的提问来源于stack exchange,提问作者Felkru
相关产品推荐
相关产品推荐

