Ant Design手动上传时如何展示Base64格式预览图片?
解决Ant Design Upload组件手动上传时Base64预览图不显示的问题
问题描述
使用Ant Design的Upload组件进行手动上传时,选择图片后无法以picture card形式展示Base64预览图,需要实现选择图片后立即显示预览的功能。
用户原代码
const FormPost = () => { const [fileList, setFileList] = useState([]); const [uploading, setUploading] = useState(false); const onFinish = (values) => { console.log('Success:', values); }; const onFinishFailed = (errorInfo) => { console.log('Failed:', errorInfo); }; const normFile = (e) => { console.log('Upload event:', e); if (Array.isArray(e)) { return e; } return e?.fileList; }; const uploadProps = { onRemove: (file) => { const index = fileList.indexOf(file); const newFileList = fileList.slice(); newFileList.splice(index, 1); setFileList(newFileList); }, beforeUpload: (file) => { setFileList([...fileList, file]); return false; }, listType: 'picture-card', fileList, }; return ( <Form layout="vertical" name="new-post" onFinish={onFinish} onFinishFailed={onFinishFailed} autoComplete="off"> <Form.Item label="Upload" valuePropName="fileList" getValueFromEvent={normFile}> <Upload {...uploadProps}> <div>New photo</div> </Upload> </Form.Item> </Form> ); };
解决方案
问题核心是:直接将浏览器返回的File对象加入fileList时,Ant Design Upload组件无法自动生成预览地址,需要手动为文件对象添加url字段(值为Base64格式的图片地址)。
修改后的完整代码:
const FormPost = () => { const [fileList, setFileList] = useState([]); const [uploading, setUploading] = useState(false); const onFinish = (values) => { console.log('Success:', values); }; const onFinishFailed = (errorInfo) => { console.log('Failed:', errorInfo); }; const normFile = (e) => { console.log('Upload event:', e); if (Array.isArray(e)) { return e; } return e?.fileList; }; const uploadProps = { onRemove: (file) => { // 通过uid匹配删除,避免引用不同导致的匹配失败 const newFileList = fileList.filter(item => item.uid !== file.uid); setFileList(newFileList); }, beforeUpload: (file) => { // 使用FileReader读取文件生成Base64预览地址 const reader = new FileReader(); reader.onload = (e) => { // 构造包含预览信息的文件对象 const newFile = { uid: file.uid, name: file.name, status: 'done', url: e.target.result, // Base64格式的预览地址 originFileObj: file // 保留原始文件对象,方便后续手动上传 }; // 函数式更新避免闭包导致的旧状态问题 setFileList(prev => [...prev, newFile]); }; reader.readAsDataURL(file); return false; // 阻止组件自动上传 }, listType: 'picture-card', fileList, }; return ( <Form layout="vertical" name="new-post" onFinish={onFinish} onFinishFailed={onFinishFailed} autoComplete="off"> <Form.Item label="Upload" valuePropName="fileList" getValueFromEvent={normFile}> <Upload {...uploadProps}> <div>New photo</div> </Upload> </Form.Item> </Form> ); };
关键说明
- 生成Base64地址:通过
FileReader的readAsDataURL方法将文件转换为Base64字符串,作为预览图的url字段值。 - 构造标准文件对象:必须包含
uid(唯一标识,用于删除匹配)、name(文件名)、status(设为done表示预览完成),同时保留originFileObj方便后续手动上传时获取原始文件。 - 优化状态更新:使用函数式更新
setFileList(prev => [...prev, newFile]),避免闭包导致的旧状态引用问题。 - 可靠删除逻辑:改用
filter通过uid匹配删除文件,比原代码的indexOf更可靠,因为新构造的文件对象与原File对象引用不同。
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

