React实现带圆形进度展示的文件上传并将文件存入组件state
自定义Antd Upload实现带圆形进度的文件上传功能
你可以基于Antd的Upload组件做二次改造,关闭默认上传逻辑,自定义上传行为和列表渲染样式即可实现需求,具体实现方案如下:
实现思路
- 关闭Upload组件的自动上传,通过
beforeUpload钩子获取文件对象,将file.originFileObj存入组件state - 自定义上传请求逻辑,通过
XMLHttpRequest监听上传进度事件,实时更新进度百分比到state - 重写Upload的
itemRender属性,自定义上传列表的渲染逻辑,展示圆形进度条、文件大小、上传百分比
核心代码示例
import { Upload, Progress, Button } from 'antd'; import { UploadOutlined } from '@ant-design/icons'; import { useState } from 'react'; const CustomUpload = () => { // 存储文件列表和对应上传进度 const [fileList, setFileList] = useState([]); const [uploadProgress, setUploadProgress] = useState({}); // 上传前钩子,获取文件存入state,阻止默认上传 const beforeUpload = (file) => { setFileList(prev => [...prev, file]); // 触发自定义上传逻辑 customUpload(file); // 返回false阻止组件默认上传行为 return false; }; // 自定义上传逻辑 const customUpload = (file) => { const formData = new FormData(); // 从file对象中取originFileObj存入formData formData.append('file', file.originFileObj); const xhr = new XMLHttpRequest(); // 监听上传进度 xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable) { const percent = Math.round((e.loaded / e.total) * 100); setUploadProgress(prev => ({ ...prev, [file.uid]: percent })); } }); // 此处替换为你的实际上传接口地址 xhr.open('POST', '/your/upload/api', true); xhr.send(formData); xhr.onload = () => { // 可根据接口返回结果补充上传成功/失败的状态处理逻辑 }; }; // 自定义上传项渲染 const itemRender = (originNode, file) => { const progress = uploadProgress[file.uid] || 0; // 文件大小格式化方法 const formatFileSize = (size) => { if (size < 1024) return size + ' B'; if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'; return (size / 1024 / 1024).toFixed(2) + ' MB'; }; return ( <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '8px 0' }}> <span>{file.name}</span> <span>{formatFileSize(file.size)}</span> {progress < 100 ? ( <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}> <Progress type="circle" size={30} percent={progress} /> <span>{progress}%</span> </div> ) : <span>上传完成</span>} </div> ); }; return ( <Upload fileList={fileList} beforeUpload={beforeUpload} itemRender={itemRender} > <Button icon={<UploadOutlined />}>选择文件</Button> </Upload> ); }; export default CustomUpload;
效果说明
- 上传前展示选择文件按钮和已选文件的名称、大小,匹配上传前的展示需求
- 上传过程中实时渲染圆形进度条和上传百分比,符合上传中的展示要求
- 所有选中的文件都可以通过
file.originFileObj从fileList状态中直接获取,满足文件存入state的需求
内容的提问来源于stack exchange,提问作者Abdul Wahab
相关产品推荐
相关产品推荐

