React使用Ant Design Upload组件上传文件控制台打印三次如何解决
问题根因
Ant Design 内置的Upload组件onChange回调的触发逻辑为:上传文件的状态每发生一次变化,就会执行一次回调。正常的文件上传流程会触发三次状态变更:
- 文件被选中加入上传队列,状态变为
uploading(上传中) - 文件上传请求执行完成,状态变为
done(上传成功)/error(上传失败) - 上传队列更新完成,触发第三次回调
你当前没有配置Upload的上传地址action,也没有阻止默认上传行为,组件会走模拟上传流程,因此会触发三次onChange,对应三次控制台打印。
修复方案
如果你不需要组件自动执行上传请求,只需要拿到选中的文件自行处理,只需要给Upload组件添加beforeUpload={() => false}属性,阻止默认的上传行为,即可切断后续多余的状态变更回调,onChange只会在文件选中时触发一次。
如果需要自定义上传逻辑,可以搭配customRequest属性覆盖默认上传逻辑。
修改后的完整代码
App.js
import React, { useState } from "react"; import 'antd/dist/antd.css'; import './index.css'; import { Row, Col, Button, Modal, Upload, message, Divider, Table } from 'antd'; import { FilePdfOutlined, AudioOutlined, DeleteOutlined } from '@ant-design/icons'; import "./App.css"; const App = () => { const [visible, setVisible] = useState(false) const showPopUp = () => { setVisible(true) } const closePopUp = () => { setVisible(false) } const uploadFile = (file) => { const filesBasket = file console.log("fileBasket", filesBasket) } const columns = [ { title: 'File', dataIndex: 'file', }, { title: 'File Name', dataIndex: 'name', }, { title: 'Actions', dataIndex: 'address', }, ]; return ( <div> <Row> <Col span={24}> <Button onClick={() => showPopUp()} type="primary">Show PopUp</Button> <Modal visible={visible} onCancel={closePopUp} onOk={closePopUp} > <div className="main"> <div style={{ marginLeft: "5px" }}> <div style={{ display: "flex" }}> <Upload accept=".pdf" beforeUpload={() => false} onChange={(e) => { uploadFile(e.file) }} > <FilePdfOutlined style={{ fontSize: "25px", backgroundColor: "red", padding: "10px", borderRadius: "50%" }} /> <h6>Upload Pdf</h6> </Upload> <Upload accept="audio/*" beforeUpload={() => false} onChange={(e) => { uploadFile(e.file) }} > <AudioOutlined style={{ fontSize: "25px", backgroundColor: "red", padding: "10px", borderRadius: "50%", marginLeft: "25px" }} /> <h6 style={{ marginLeft: "25px" }}>Upload Audio</h6> </Upload> </div> </div> </div> <Divider /> <Table columns={columns} size="small" /> </Modal> </Col> </Row> </div> ) } export default App
App.css(无需修改)
.ant-modal-close-x > span { display: none; } .ant-upload-list { display: none; }
内容的提问来源于stack exchange,提问作者Cruse
相关产品推荐
相关产品推荐

