首页 > 其他分享 >使用`react-hooks写法`对`antd的Upload.Dragger上传组件`进行二次封装

使用`react-hooks写法`对`antd的Upload.Dragger上传组件`进行二次封装

时间:2024-02-25 21:58:26浏览次数:22  
标签:console hooks Dragger Upload theOptions theFileList file props data

使用react-hooks写法antd的Upload.Dragger上传组件进行二次封装

预期

  1. antdUpload.Dragger组件进行二次封装,让它的使用方法和Upload.Dragger组件保持一致。
  2. 让该组件能自动把数据放到对应后端服务器中。
  3. 让该组件能的 value 值如果没上传,为数组形式。如果没有值,为空数组。如果有值,都为数组的项。

代码示例

// CustomDraggerUpload.tsx

import { InboxOutlined } from "@ant-design/icons";
import { request } from "@umijs/max";
import { Upload } from "antd";
import { UploadProps } from "antd/lib/upload/interface";
import React, { useEffect, useState } from "react";

// import styled from 'styled-components';
import { createGlobalStyle } from "styled-components";
const GlobalStyles = createGlobalStyle`
  .CustomDraggerUploadContainer {
    &.is-the-check {
      .ant-upload-drag {
        display: none;
      }
    }
  }
`;

interface CustomDraggerUploadProps extends UploadProps {
  fileList?: UploadProps["fileList"];
  value?: UploadProps["fileList"];
  onFileListChange?: (fileList: UploadProps["fileList"]) => void;
  noUpload?: boolean;
}

const theFileUpload = `/api/file/upload`; //后端提交文件接口。

const CustomDraggerUpload: React.FC<CustomDraggerUploadProps> = (props) => {
  const theProps = { ...props };
  delete theProps.value;
  delete theProps.disabled;
  delete theProps.fileList;
  delete theProps.onChange;

  const [theDisabled, setTheDisabled] = useState(props?.disabled || false);
  useEffect(() => {
    setTheDisabled(props?.disabled || false);
  }, [props?.disabled]);

  // 自动控制已上传列表;
  let [theFileList, setTheFileList] = useState<UploadProps["fileList"]>(
    props?.value || []
  );
  useEffect(() => {
    console.log(`props?.value-->`, props?.value);
    // 父组件在onChange事件中,大概率会把传出的theFileList赋值给porps.fileList中,防止死循环;
    if (theFileList === props?.value || !props?.value) {
      return;
    }
    setTheFileList(props?.value || []);
  }, [props?.value]);

  // useEffect(() => {
  //   // 这个是为了给父组件传一个onChange事件;

  //   if (theFileList === props?.value) {
  //     return;
  //   }

  //   props?.onChange?.(theFileList); //兼容antd的校验机制;
  // }, [theFileList]);

  const theUploadProps: UploadProps = {
    fileList: theFileList,
    progress: {
      strokeColor: {
        "0%": "#108ee9",
        "100%": "#87d068",
      },
    },
    onChange: async (info) => {
      if (props?.noUpload) {
        console.log(
          `不可上传,只能处理onChange: props?.noUpload-->`,
          props?.noUpload
        );
        return;
      }

      console.log(`列表数据变动事件onChange: info`, info);
      setTheFileList(info?.fileList || []);
      props?.onChange?.(info?.fileList || []); //兼容antd的校验机制;
    },
    customRequest: async (theOptions) => {
      if (props?.noUpload) {
        console.log(
          `不可上传,只能处理customRequest: props?.noUpload-->`,
          props?.noUpload
        );

        return;
      }

      const formData = new FormData();
      // console.log(`自定义上传事件: theOptions`, theOptions);
      formData.append("file", theOptions.file, theOptions.file.name);
      try {
        // 这个接口是后端给的,用于把文件上传到后端的服务器;
        interface ApiResponse {
          code: number; // 状态码;
          msg: null | string; // 消息,可以为 null 或字符串;
          data: {
            uuid: string; // 文件 UUID;
            sysFileName: string; // 文件名;
            sysFileExtension: string; // 文件扩展名;
            sysFileSize: number; // 文件大小(字节);
            sysCreateTime: string; // 文件创建时间;
            url: string; // 文件绝对URL;
            sysFileStoragePath: string; // 文件相对路径;
          };
          error: boolean; // 是否有错误;
          success: boolean; // 是否成功;
        }

        setTheDisabled(true);
        const res = await request<ApiResponse>(theFileUpload, {
          data: formData,
          method: "POST",
          onUploadProgress: (data) => {
            console.log(`上传中data`, data);

            // let { total, loaded } = data;
            let params = {
              percent: Math.round((data.loaded / data.total) * 100).toFixed(2),
            };
            theOptions.file.percent = Number(params.percent);
            theOptions.file.status = `uploading`;
            if (theOptions.file.percent >= 100) {
              theOptions.file.status = `done`;
            }
            // console.log(`theOptions.file`, theOptions.file);

            const theList = [
              theOptions.file,
              ...theFileList.filter((item) => item.uid !== theOptions.file.uid),
            ];
            theFileList = theList;
            setTheFileList(theList);
            props?.onChange?.(theList); //兼容antd的校验机制;
            theOptions?.onProgress?.(params, theOptions.file);
          },
        });
        console.log(`res`, res);

        if (res?.code !== 200) {
          throw new Error(`上传不成功`);
        }

        console.log(
          `自定义上传成功: theOptions`,
          theOptions,
          `\n theFileList`,
          theFileList
        );
        const theList = [
          {
            ...(res?.data || {}),
            uid: res?.data?.uuid,
            sysFileUuid: res?.data?.uuid,
            url: res?.data?.url,
            name: res?.data?.sysFileName,
            sysFileName: res?.data?.sysFileName,
            status: "done",
          },
          ...theFileList.filter((item) => item.uid !== theOptions.file.uid),
        ];
        theFileList = theList;
        setTheFileList(theList);
        props?.onChange?.(theList); //兼容antd的校验机制;
      } catch (error) {
        console.log(`error`, error);
        theFileList =
          theFileList?.filter((item) => item.uid !== theOptions.file.uid) || [];
        setTheFileList(theFileList);
        props?.onChange?.(theFileList); //兼容antd的校验机制;
      } finally {
        setTheDisabled(false);
      }
    },
  };

  // console.log(`上传组件: props-->`, props);
  // console.log(`上传组件: theFileList-->`, theFileList);

  return (
    <>
      <GlobalStyles />
      <Upload.Dragger
        {...theUploadProps}
        {...theProps}
        disabled={theDisabled}
        rootClassName={`CustomDraggerUploadContainer ${
          theDisabled ? `is-the-check` : ``
        }`}
      >
        {!props?.noUpload && (
          <>
            <div>
              <InboxOutlined />
            </div>
            <div>单击或拖动文件到此区域进行上传</div>
          </>
        )}
      </Upload.Dragger>
    </>
  );
};

export default CustomDraggerUpload;

进阶参考

  1. antd-Upload.Dragger拖拽上传组件;

标签:console,hooks,Dragger,Upload,theOptions,theFileList,file,props,data
From: https://www.cnblogs.com/fangchaoduan/p/18033139

相关文章

  • 为什么 Hooks,千万不要在 if 语句或者 for 循环语句中使用!
    如果组件中多次使用useState怎么办?React如何“记住”哪个状态对应哪个变量?React是完全根据useState的调用顺序来“记住”状态归属的,假设组件代码如下:constCounter=()=>{const[count,setCount]=useState(0);const[foo,updateFoo]=useState('foo');......
  • upload-labs
    Pass-01前端js验证谷歌设置->隐私安全->网站设置->JavaScript修改为不允许使用JavaScript上传php文件复制图片地址蚁剑连接文件上传成功Pass-02MIME是一种类型(例如:text,image),MIME是一种标准,是用来表示文档,文件或字节流的性质和格式(告诉浏览器这个文件的类型,目的跟文件扩展......
  • 使用 Docker 搭建 Jenkins 与 GitLab 环境,实现触发 Webhooks 构建
    参考https://blog.csdn.net/xueqinglalala/article/details/120883554https://blog.csdn.net/anqixiang/article/details/104968469https://dirask.com/questions/Gitlab-Jenkins-how-to-fix-Error-403-No-valid-crumb-was-included-in-the-request-DWewGjhttps://www.zhih......
  • DVWA-File Upload(文件上传漏洞)
    FileUpload文件上传漏洞是通过上传文件功能,上传一些可执行的脚本文件,且服务器端没有对上传的文件进行严格的校验或者在服务器端没有对上传的文件进行安全策略的配置,导致文件能成功上传到服务器上,且能够解析执行。DVWA-FileUpload的级别:--low--medium--high......
  • Debug : kfp.Client().upload_pipeline(): Failed to start a transaction to create
    [ERROR:Failedtostartatransactiontocreateanewpipelineandanewpipelineversion:dialtcp:lookupmysqlon10.96.0.10:53:nosuchhost","]>>>kfp.Client().upload_pipeline("/home/maye/pipeline_wafer_distribute.yaml",......
  • 【漏洞复现】用友NC-Cloud系统uploadChunk存在任意文件上传漏洞
    阅读须知花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。本......
  • el-upload分片上传到七牛
    参考: https://blog.csdn.net/So_cute_girl/article/details/118606647需要自定义上传方法http-request,用七牛的分片上传<template><el-uploaddrag:limit="1"action="https://up.qiniup.com":multiple="false"accept=".mp4":d......
  • upload文件上传
    Upload-Labs-Linux靶场通关关卡1~2上传.png格式文件,burp后台改成.php即可通关关卡3拦截黑名单不全,在关卡2的基础上改成php3即可(如果靶场是phpstudy搭建,可能需要点击其他选项->打开配置文件->httpd-conf)关卡4关于AddType命令的作用解释 AddType指令作用:在......
  • CTFer——文件操作与upload-labs解析
    一、什么是webshellwebshell就是以aspx、php、jsp等网页文件形式存在的一种命令环境也可以将其称为一种网页后门 黑客在入侵网站后,通常会将jsp、aspx或php后门文件与网站服务器web目录下正常的网页文件混在一起然后就可以使用浏览器来访问后门文件,得到一个命令执行环境,以达......
  • antd upload组件缩略图自定义
    antd组件的缩略图使用img标签即可实现,我们这里有一个3D文件显示2D缩略图的需求,而这个缩略图是后台从接口返回的,所以需要自定义缩略图。 这里的imageUrl就是你要的缩略图用到了官网案例的将图片转为base64,具体的方法看官网。在这里还有最最重要的一个点就是得控制它的样式,不......