现在的上传组件基本上都要要求实现文件预览的功能。而antd这个组件库的upload组件刚好都能够达到我的要求。这里是我在使用中发现的一个小坑,给大家分享一下。
import React, { useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import { Upload, Progress, Modal, message } from 'antd';
import type { UploadFile, UploadProps } from 'antd';
type FileType = File;
const VideoUpload: React.FC = () => {
const [previewOpen, setPreviewOpen] = useState(false);
const [previewVideo, setPreviewVideo] = useState('');
const [fileList, setFileList] = useState<UploadFile[]>([]);
const handlePreview = (file: UploadFile) => {
if (!file.url && !file.preview) {
const url = URL.createObjectURL(file.originFileObj as FileType);
file.preview = url;
}
setPreviewVideo(file.url || (file.preview as string));
setPreviewOpen(true);
};
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>
setFileList(newFileList);
const handleRemove = (file: UploadFile) => {
URL.revokeObjectURL(file.preview || '');
return true;
};
const uploadButton = (
<div>
<PlusOutlined />
<div style={{ marginTop: 8 }}>上传视频</div>
</div>
);
return (
<>
<Upload
// accept="video/*"
listType="picture-card"
fileList={fileList}
onPreview={handlePreview}
onChange={handleChange}
onRemove={handleRemove}
>
{fileList.length >= 3 ? null : uploadButton}
</Upload>
{fileList.map(file => (
<div key={file.uid} style={{ marginTop: 8 }}>
<Progress percent={file.percent} status={file.status} />
</div>
))}
<Modal open={previewOpen} title="视频预览" footer={null} onCancel={() => setPreviewOpen(false)}>
<video controls style={{ width: '100%' }}>
<source src={previewVideo} type="video/mp4" />
您的浏览器不支持视频标签。
</video>
</Modal>
</>
);
};
export default VideoUpload;
这是我一开始的做法,可以看到在upload组件上我使用了 onPreview={handlePreview} 回调函数,
照理说他应该是提供预览功能的促发条件,像这样:
实际上运行后
仔细查看文档:
我好像处理的没有问题 ?那就与组件没有问题,然后我打印了下上传的组件,发现了问题所在
打印出来后是这样的
每上传触发一次,它会打印三次。
接下来有趣的来了
我这样试了下,结果是
我以为它是异步的没问题,但结果它确实是执行了三遍,我跟着debugger走了一圈,发现它是整个页面组件都执行了三遍,所以打印出三个1,ok没问题!扯远了。随后发现它是否显示,是与status状态有关,也就是它是异步的,但是渲染是同步的,
最后改成这样,问题解决,但是有个问题,万一上传不成功呢。虽然不影响不能预览这个功能。我会持续关注这个功能的!!!