有一个需求,需要上传文件,但是在上传文件之前希望能先检查用户能否上传(权限或者证书等校验) 上传文件前端用的开发框架是React, 组件库使用Ant Design,所以上传文件选择使用Upload组件。
最开始看文档是打算beforeUpload
的,文档中具体说明是:
上传文件之前的钩子,参数为上传的文件,若返回
false
则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入File
或Blob
对象则上传 resolve 传入对象);也可以返回Upload.LIST_IGNORE
,此时列表中将不展示此文件。 注意:IE9 不支持该方法
这里将文件上传的步骤简化描述下,分为三步:用户点击按钮------弹出文件选择框选择文件------上传文件
beforeUpload
是在上传文件之前调用的,也就是在弹出文件选择框选择文件之后,上传文件支持。实际测试也是如何,在弹出文件选择框后,beforeUpload
才被调用
而我希望实现的效果是在用户点击按钮后就进行检查,检查通过后才弹出文件选择框,所以beforeUpload
不能用。
后面考虑了两个方案:
- 隐藏掉
Upload
的Button
,显式另一个Button
,点击该按钮时进行检查,检查通过后在通过代码调用Upload
的Button
的click()
触发上传操作 Upload
有提供openFileDialogOnClick
属性,将其设置为false
可以不弹出文件框。所以可以考虑先将其设置为false
,然后给Upload
的按钮增加点击事件,在里面先做检查,检查通过后将openFileDialogOnClick
设置为true
,然后再触发click()
第一个方案需要增加一个Button
,第二个方案则需要设置openFileDialogOnClick
,两个方案都需要在事件里面再触发click()
最后选择了第二个方案来实现,具体实现代码如下
typescript
import React, {useEffect, useState, useRef} from "react";
import {PageHeaderWrapper} from "@ant-design/pro-layout";
import {Button, Card, Col, message, Row, Upload} from "antd";
const UpdateManage: React.FC = () => {
const [openFileDialog, setOpenFileDialog] = useState<boolean>(false)
const uploadButtonRef = useRef()
async function doCheckLicense() {
// do something ...
}
return (
<PageHeaderWrapper>
<Card>
<Row gutter={[8, 16]} style={{marginBottom: 20}}>
<Col span={3}>
<Upload
name = 'file'
openFileDialogOnClick={openFileDialog}
showUploadList={false}
>
<Button
type="primary"
onClick={()=>{
if(openFileDialog == false){
doCheck().then(res => {
if(res.success) {
setOpenFileDialog(true)
setTimeout(() => {
uploadButtonRef.current.click()
}, 50)
} else {
message.error("not pass check")
}
}).catch((error) => {
message.error("error")
})
}
}}
ref={uploadButtonRef}
>Upload</Button>
</Upload>
</Col>
</Row>
</Card>
</PageHeaderWrapper>
)
}
export default UpdateManage