react18中antd的Upload组件上传头像,并且拿到服务器返回的头像的url地址在页面中显示头像

Posted 阿jin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react18中antd的Upload组件上传头像,并且拿到服务器返回的头像的url地址在页面中显示头像相关的知识,希望对你有一定的参考价值。

业务需求:上传头像,上传完毕后拿到头像的url,把头像展示在页面中,最终把头像url和其他用户信息一起发送给服务器

 

上传头像流程

 

导入 Upload 组件和图标(一个加号,一个加载中)

import  Upload  from \'antd\';
import  PlusOutlined, LoadingOutlined  from \'@ant-design/icons\';

 

定义状态

const index = memo(() => 
  // 用于上传前和上传时切换
  const [loading, setLoading] = useState(false);

  // 用于保存服务端返回的头像url
  const [imageUrl, setImageUrl] = useState();

 

定义一个上传状态组件,上传前显示 + 号,上传时显示loading

const index = memo(() => 
  const uploadButton = (
    <div>
      loading ? <LoadingOutlined /> : <PlusOutlined />
      <div
        style=
          marginTop: 8,
        
      >
        上传
      </div>
    </div>
  );

 

组件代码(省略其他...)

const index = memo(() => 
  return (
    <Upload
      listType="picture-card" // 上传列表的内建样式
      showUploadList=false // 是否展示文件列表
      action="" // 这里填写上传的地址
      beforeUpload=beforeUpload // 上传前执行的操作
      onChange=handleChange // 上传中、完成、失败都会调用这个函数。
      name=\'avatar\' // 传递给后端的字段
    >
      imageUrl ? (
        <img
          src=imageUrl
          alt="avatar"
          style=
            width: \'100%\',
          
        />
      ) :  (uploadButton)
    </Upload>
  )
)

 

定义头像上传前执行的钩子函数

const index = memo(() => 
  // 该函数会在上传前执行,会把file对象传过来,可以对上传的文件类型判断,限制大小等
  const beforeUpload = (file) => 
    const isJpgOrPng = file.type === \'image/jpeg\' || file.type === \'image/png\';
    if (!isJpgOrPng) 
      message.error(\'只能上传 JPG/PNG 文件!\');
    
    const isLt1M = file.size / 1024 / 1024 < 1;
    if (!isLt1M) 
      message.error(\'图片不能超过1MB!\');
    
    return isJpgOrPng && isLt1M;
  ;
)

 

定义头像上传后执行的钩子函数

const index = memo(() => 
  const handleChange = (info) => 
      if (info.file.status === \'uploading\') 
        setLoading(true);
        return;
      
      // 当上传完毕
      if (info.file.status === \'done\') 
          setLoading(false);
        // 判断是否上传成功
        if (info.file.response.code === 200) 
          // 把返回的图像地址设置给 imageUrl
          setImageUrl(info.file.response.data.imageUrl) // 取决于服务端返回的字段名
        
      
    ;
)

 

以下是在控制台输出 info 对象

 

完整demo

import React,  memo, useState  from \'react\'
import  UserWrapper  from \'./style\'

import  Upload  from \'antd\';
import  PlusOutlined, LoadingOutlined  from \'@ant-design/icons\';

const index = memo(() => 

  const [loading, setLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState();
  
  const beforeUpload = (file) => 
    const isJpgOrPng = file.type === \'image/jpeg\' || file.type === \'image/png\';
    if (!isJpgOrPng) 
      message.error(\'只能上传 JPG/PNG 文件!\');
    
    const isLt1M = file.size / 1024 / 1024 < 1;
    if (!isLt1M) 
      message.error(\'图片不能超过1MB!\');
    
    return isJpgOrPng && isLt1M;
  ;

  const handleChange = (info) => 
    if (info.file.status === \'uploading\') 
      setLoading(true);
      return;
    
    if (info.file.status === \'done\') 
      if (info.file.response.code === 200) 
        setLoading(false);
        setImageUrl(info.file.response.data.imageUrl)
      
    
  ;

  const uploadButton = (
    <div>
      loading ? <LoadingOutlined /> : <PlusOutlined />
      <div
        style=
          marginTop: 8,
        
      >
        上传
      </div>
    </div>
  );
  
  return (
    <Upload
      listType="picture-card"
      className="avatar-uploader"
      showUploadList=false
      action="上传的地址"
      beforeUpload=beforeUpload
      onChange=handleChange
      name=\'avatar\'
    >
      imageUrl ? (
        <img
          src=imageUrl
          alt="avatar"
          style=
            width: \'100%\',
          
        />
      ) : (
        uploadButton
      )
    </Upload>
  )
)

export default index

Antd的Upload组件上传文件控制文件数量格式等,以及提交时如何获取文件

背景:使用React的antd组件的Upload(官网),要求文件上传后,在点击提交时再将文件传过去。
技术点:

  1. 完全控制的文件上传。
  2. 可控制上传数量。
  3. 控制文件格式。
  4. 移除时的事件onRemove。
  5. 状态、数量改变onChange事件等。
  6. 是否带cookie,withCredentials: true。
  7. 提交时,originFileObj属性获取原始文件。

页面大致是这样:

Upload代码如下:

const [fileList, setFileList] = useState([]);
// upload属性
const uploadProps = 
    name: 'file',
    action: getFullUrl('/card/upload'),
    withCredentials: true, // 文件上传时带cookie
    onChange: handleChange,
    onRemove: handleReset, // 点击文件后的小垃圾桶图标,移除
    beforeUpload: (file) => 
      const  name  = file;
      // 校验是否是excel文件
      const isExcel = /(xls|xlsx)$/i.test(name);
      if (!isExcel) 
        message.error(I18n.get('batch.card.upload.excel'));
      
      // 自定义属性
      file.isExcel = isExcel;
      return isExcel;
    ,
  ;
// return中渲染:
<Upload ...uploadProps fileList=fileList>
    <Button>
      <Icon type="upload" />点击上传
    </Button>
 </Upload>

防止一次代码太长,分开写,处理函数可以根据具体需求定义。
上面代码中的具体函数:

 const handleChange = ( file, fileList ) => 
    try 
      const  status, response  = file;
      // 刚才的子定义属性,是否是Excel文件,通过校验
      if (!file.isExcel) 
        return;
      
      // 只能上传一个文件,不能用flie直接设置,onRemove函数会触发handleChange
      setFileList(fileList.slice(-1));
      if (status === 'error') 
        throw new Error('上传失败');
      
      if (status === 'done' && response) 
        const  code  = response;
        // ...
      
     catch (e) 
      message.error(e.message);
    
  ;
  // 这里是只有一个文件,移除即清空文件列表
  const handleReset = () => 
    setFileList([]);
  ;
 // 点击提交,formData的形式传参
  const handleSubmit = async () => 
    try 
      const formData = new FormData();
      formData.append('file', fileList[0].originFileObj);
      const res = await submitBatchFile(formData);
      const  code  = res;
      if (code !== '000000') 
        throw new Error('提交失败');
      
      message.success('提交成功');
     catch (e) 
      console.error(e);
      message.error(e.message);
    
  ;

以上是关于react18中antd的Upload组件上传头像,并且拿到服务器返回的头像的url地址在页面中显示头像的主要内容,如果未能解决你的问题,请参考以下文章

antd Upload组件 onChange接收不到后续状态的问题

antd的Upload组件 在安卓机上直接打开相册

Antd的Upload组件上传文件控制文件数量格式等,以及提交时如何获取文件

Antd的Upload组件上传文件控制文件数量格式等,以及提交时如何获取文件

antd的upload组件上传功能踩坑

react--封装上传组件