React使用Dropzone上传图片时File对象src属性访问为undefined问题
问题根因
你代码的核心问题是没有等待FileReader的异步读取操作完成就提前更新了状态。FileReader.readAsDataURL是异步API,你在map中返回img对象时,Promise还处于pending状态,img.src还没被赋值,此时存入state的图片对象是没有src属性的。
现象解释
- 直接打印
imgs[0]能看到src属性:浏览器控制台打印对象时保存的是对象的引用,你点击展开对象查看属性时,FileReader的异步回调已经执行完成,src已经被追加到对象上,所以能看到对应值。 - 打印
imgs[0].src返回undefined:该语句取的是代码执行到此处时的即时属性值,此时异步操作还没完成,src还没被赋值,所以返回undefined。 - 新增第二张图片时能正常读取第一张的src:两次操作的间隔已经足够第一张图片的FileReader异步执行完成,src已经被赋值,所以可以正常读取。
修复方案
调整handleAddImages逻辑,用Promise.all等待所有图片的base64转换完成后再更新状态:
const handleAddImages = async (inputImages: any[]): Promise<void> => { // 等待所有FileReader异步操作完成 const imagesWithSrc = await Promise.all( inputImages.map((img) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => { // 赋值完成后再返回带src的图片对象 img.src = reader.result as string; resolve(img); }; reader.onerror = reject; reader.readAsDataURL(img); }); }) ); const nextImages = [...currentImages, ...imagesWithSrc]; handleOnChange({ target: { name: "images", value: nextImages, }, }); };
修改后状态中存储的图片对象一定是已经完成base64转换、带有src属性的,渲染预览时就不会出现src为undefined的问题。
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

