Ant Design多文件上传:fileList中所有文件base64值重复问题
解决Ant Design多文件上传时base64重复的问题
嘿,我看了你的代码,很快就发现了两个导致所有文件共用同一个base64的问题,咱们一步步来修复:
问题1:读取了错误的文件对象
你在forEach循环里写的是reader.readAsDataURL(info.file.originFileObj),这里的info.file是当前触发onChange事件的单个文件(比如批量选文件时,这个值其实是最后一个被选中的文件),所以循环里所有的FileReader都在读取同一个文件,自然得到相同的base64。
应该改成读取循环当前的file对象的originFileObj:reader.readAsDataURL(file.originFileObj)。
问题2:异步操作未正确处理
FileReader的onload是异步触发的,你在启动所有reader后立刻调用setState,这时候所有的base64还没被读取完成,状态更新后fileList里的base64属性可能还没赋值,甚至会因为异步顺序导致数据混乱。
我们可以把每个文件的读取操作包装成Promise,等所有Promise都完成后再统一更新state。
修改后的完整代码
import React from 'react'; import { Upload } from 'antd'; export default class MultiUpload extends React.Component { constructor(props: any) { super(props); this.state = { fileList: [] }; this.handleUpload = this.handleUpload.bind(this); } handleUpload = async (info: any) => { let fileList = [...info.fileList]; // 只保留最后5个文件 fileList = fileList.slice(-5); // 把每个文件的base64读取操作包装成Promise const filePromises = fileList.map(file => { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => { // 给当前文件添加base64属性 file.base64 = e.target.result; resolve(file); }; // 读取当前循环的文件对象 reader.readAsDataURL(file.originFileObj); }); }); // 等待所有文件都读取完成 const updatedFileList = await Promise.all(filePromises); this.setState({ fileList: updatedFileList }); }; componentDidUpdate(prevProps, prevState) { console.log(this.state); } render() { return ( <div> <Upload listType={"text"} multiple={true} onChange={this.handleUpload}> <button> Upload </button> </Upload> </div> ) } };
关键改动说明
- 用
map替代forEach,把每个文件的读取过程包装成Promise,这样可以用Promise.all等待所有异步操作完成 - 每个Promise里读取当前循环的
file.originFileObj,确保每个文件对应自己的base64 - 使用
async/await语法等待所有Promise完成后再更新state,保证fileList里的每个文件都已经带上了正确的base64值
这样修改后,你再上传多个文件,每个文件的base64就都是各自对应的字符串啦!
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

