多Dropzone单提交按钮上传异常:仅传1个却提交3个问题排查
单文件上传触发三次上传的问题排查与修复
问题描述
拥有3个Dropzone区域,每个区域仅接受特定类型文件,通过一个提交按钮提交所有已上传文件。使用csvFile、emailFile、domainFile三个React状态存储文件,但点击提交按钮时,即使仅上传1个文件,也会触发3次上传操作。
原因分析
- 未过滤空文件状态:
allFiles = [csvFile, emailFile, domainFile]包含了所有状态,哪怕某个状态未上传文件(值为undefined),也会进入循环执行上传逻辑,导致空文件也触发请求。 - 循环内参数错误:
map循环中错误使用了函数参数file,而非当前遍历的file_,导致每次循环都用同一个错误的文件信息。- 每次调用
uploadList时都传入了所有三个文件状态,而非当前遍历的单个文件,造成重复上传全部文件。
- else分支逻辑错误:
forEach循环同样未过滤空文件,且错误传入函数参数file,而非当前的file_。
修复后的代码
const [csvFile, setCsvFile] = React.useState(); const [emailFile, setEmailFile] = React.useState(); const [domainFile, setDomainFile] = React.useState(); const handleSubmit = async () => { // 过滤掉未上传的空文件,同时保留文件类型标识 const validFiles = [ { type: 'csv', file: csvFile }, { type: 'email', file: emailFile }, { type: 'domain', file: domainFile } ].filter(item => item.file); if (validFiles.length === 0) { toast('请至少上传一个文件'); return; } setDisabled(true); if (!listId) { await Promise.all( validFiles.map(({ file, type }) => { const formData = { name: _.get(file, 'meta.name', ''), }; return dispatch(createListAction(formData)) .then((response) => { const listIdentifier = _.get(response, 'data.id'); // 仅上传当前遍历的单个文件 uploadList({ [type]: file }, listIdentifier); }) .catch((error) => { toast((t) => <Toast toastId={t} error={error} />, { duration: Infinity }); console.error(error); }); }), ); } else { // 仅遍历有效文件,上传对应单个文件 validFiles.forEach(({ file, type }) => { uploadList({ [type]: file }, listId); }); } };
关键修复点
- 过滤空文件:将文件与类型绑定后过滤掉未上传的项,确保仅处理已上传的文件。
- 修正循环参数:使用遍历项的
file而非函数参数,避免错误复用值。 - 单个文件上传:调用
uploadList时仅传入当前遍历的单个文件,而非全部三个状态,避免重复上传。 - 增加空文件判断:提前校验是否有有效文件,避免无文件时执行后续逻辑。
内容的提问来源于stack exchange,提问作者Jennifer De Goede
相关产品推荐
相关产品推荐

