React JS多图上传问题:Chrome/Brave无法重新上传已删除图片
问题:React多图上传在Chrome/Brave中删除后无法重新上传同一张图片
这段React多图上传代码在Mozilla Firefox中运行正常,但在Google Chrome和Brave浏览器存在异常:上传一张图片、删除该图片后,尝试重新上传同一张图片时,图片既无法上传也不会在预览区域显示,且selectImages函数中的console.log(files)没有任何日志输出。
原代码
const selectImages = (e) => { e.preventDefault(); const files = [...e.target.files]; console.log(files) let newImages = [...images, ...files]; console.log('total images :' , newImages ) if (newImages?.length > 5) { newImages = newImages.slice(0, 5); } const newImagePreviews = newImages.map((file, index) => { return { id: index, name: file.name, url: URL.createObjectURL(file), }; }); setImages(newImages); setImagePreviews(newImagePreviews); }; const deleteImage = (index) => { const updatedImages = [...images]; const updatedPreviews = [...imagePreviews]; updatedImages.splice(index, 1); updatedPreviews.splice(index, 1); console.log('updatedImages : ',updatedImages) setImages(updatedImages); setImagePreviews(updatedPreviews); }; // 渲染部分 <input type="file" accept="image/*" multiple id="imageUpload" style={{ display: 'none' }} onChange={selectImages} /> <div className="image-previews"> {imagePreviews.map((image, index) => { return ( <div className="image" key={index}> <img src={image.url} /> <p className="file-name">{image.name}</p> <div className="delete"> <button onClick={() => deleteImage(index)}>{t('DELETE')}</button> </div> </div> ) })} </div>
问题原因
Chrome、Brave这类基于Chromium内核的浏览器,当<input type="file">的文件选择没有发生变化时,不会触发onChange事件。删除图片后重新选择同一张,此时input的value和之前选中时一致,所以事件不会被触发,也就不会执行selectImages函数。而Firefox的行为逻辑不同,即使选择相同文件也会触发onChange。
解决方案
在selectImages函数处理完文件后,手动重置input的value为null,这样下次选择同一张图片时,input的value会从null变为文件路径,触发onChange事件。
修改后的selectImages函数:
const selectImages = (e) => { e.preventDefault(); const files = [...e.target.files]; console.log(files) let newImages = [...images, ...files]; console.log('total images :' , newImages ) if (newImages?.length > 5) { newImages = newImages.slice(0, 5); } const newImagePreviews = newImages.map((file, index) => { return { id: index, name: file.name, url: URL.createObjectURL(file), }; }); setImages(newImages); setImagePreviews(newImagePreviews); // 新增:重置input的value e.target.value = null; };
额外优化建议
- 避免使用
index作为列表元素的key,可以用file.name + Date.now()这类更唯一的标识,防止列表更新时出现渲染异常。 - 记得在组件卸载时调用
URL.revokeObjectURL释放图片预览的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者ksd030687d
相关产品推荐
相关产品推荐

