Ant Design Upload组件onChange无法实时更新React Hooks进度
解决Ant Design目录上传进度实时更新问题
问题分析
你的代码存在两个核心问题导致进度无法实时更新:
- 直接修改状态变量:
setUploadingFilesCount((uploadingFilesCount += 1))直接修改状态变量,违反React状态不可变原则,且状态更新是异步的,此处拿到的uploadingFilesCount并非最新值。 - 闭包捕获旧值:
handleChange里的uploadingFilesCount和filesInFolder可能被闭包捕获旧值,导致百分比计算不准确,进而setUploadProgress无法实时触发组件更新。
修正方案
调整后的代码如下,关键修改点已标注:
import { useState } from 'react'; import { Form, Upload, Button, Progress } from 'antd'; import { UploadOutlined } from '@ant-design/icons'; export const UploadDirectory: React.FC<UploadDirectoryProps> = () => { const [uploadProgress, setUploadProgress] = useState<number>(0); // 用useState明确管理已上传文件数,初始值设为0 const [uploadingFilesCount, setUploadingFilesCount] = useState<number>(0); // 假设filesInFolder也通过useState管理 const [filesInFolder, setFilesInFolder] = useState<number>(0); const handleChange = (data: any) => { const totalFiles = filesInFolder; if (totalFiles === 0) return; // 避免除以0的情况 // 用函数式更新获取最新已上传数,规避闭包问题 setUploadingFilesCount(prevCount => { const newCount = prevCount + 1; // 在状态更新回调内计算进度,确保数值都是最新的 const percentage = Math.ceil((newCount / totalFiles) * 100); setUploadProgress(percentage); return newCount; }); }; // 可选:添加进度重置逻辑,用于重新上传场景 const resetProgress = () => { setUploadProgress(0); setUploadingFilesCount(0); }; return ( <div> <Form.Item label="上传目录" name={"uploadDirectory"}> <Upload directory onChange={handleChange} beforeUpload={() => { resetProgress(); // 开始上传前重置进度 return false; // 根据业务逻辑调整是否阻止自动上传 }} name={"uploadFolder"} > <Button icon={<UploadOutlined />}>选择目录上传</Button> </Upload> </Form.Item> <Progress type="circle" percent={uploadProgress} /> </div> ); };
关键修改说明
- 状态更新方式:使用
setUploadingFilesCount(prev => prev + 1)的函数式更新,确保每次获取的都是最新状态值,避免异步更新导致的数值偏差。 - 进度计算时机:在状态更新的回调内直接计算进度,保证
newCount和totalFiles都是最新值,让setUploadProgress能实时更新进度。 - 进度重置:新增
resetProgress函数,在开始新上传时重置进度,避免上次进度残留。
另外需要确保filesInFolder能正确获取目录下的文件总数,比如用户选择目录后,通过Upload相关API或自定义逻辑统计文件数量,这是进度计算的基础。
内容的提问来源于stack exchange,提问作者Haydenn Harper
相关产品推荐
相关产品推荐

