You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kendo React Upload如何通过对应事件实现自定义上传/删除

Kendo React Upload 全自定义上传/删除实现方案

要完全屏蔽组件默认的saveUrl/removeUrl请求,自主管控上传、元数据入库、删除全流程,按以下步骤配置即可:

核心前提

  • 组件默认请求触发的必要条件是传入saveUrl或removeUrl属性,只要不在组件上配置这两个属性,组件本身不会主动发起任何默认的上传、删除接口请求。

具体实现步骤

  • 改用受控模式管理文件列表
    不要用defaultFiles做一次性初始化,换成组件的受控属性files绑定本地自主维护的状态,所有文件的新增、状态变更、删除都由你手动更新状态,完全接管组件的文件流转逻辑。基础配置示例:

    import { Upload, UploadFileInfo, UploadFileStatus } from '@progress/kendo-react-upload';
    
    // 本地维护全量文件列表,初始值为已上传的历史文件
    const [fileList, setFileList] = useState<UploadFileInfo[]>(initialHistoryFiles);
    
    <Upload
      autoUpload={false}
      files={fileList} // 受控模式绑定本地状态
      // 新增文件回调
      onAdd={(e) => {
        e.preventDefault(); // 阻断组件内部默认新增逻辑
        // 把新选中的待上传文件合并到本地列表
        setFileList(prev => [...prev, ...e.affectedFiles]);
      }}
      onRemove={handleRemove}
    />
    
  • 自定义删除逻辑实现
    在onRemove回调中阻断默认行为,自行区分文件类型调用删除接口,操作完成后手动更新本地文件列表:

    const handleRemove = (e) => {
      e.preventDefault(); // 必须加,阻断组件默认删除请求和状态流转
      const needRemoveFiles = e.affectedFiles;
    
      needRemoveFiles.forEach(async (file) => {
        // 已上传的历史文件:调用自定义删除接口,同步删除文件存储和数据库元数据
        if (file.status === UploadFileStatus.Uploaded || file.serverFileId) {
          await customDeleteApi({
            fileId: file.serverFileId,
            // 其他你需要的元数据参数
          });
        }
        // 待上传的临时文件不需要调接口,直接从本地列表移除即可
        setFileList(prev => prev.filter(item => item.uid !== file.uid));
      });
    };
    
  • 自定义上传逻辑实现
    不要依赖组件内部的上传触发按钮和onStatusChange里的Uploading状态判断,自己在组件外部加独立的上传触发按钮,点击后手动遍历待上传文件,逐个调用上传接口、写入元数据,同步更新文件状态:

    // 外部上传按钮点击逻辑
    const triggerCustomUpload = async () => {
      // 筛选出所有待上传的文件
      const pendingUploadFiles = fileList.filter(
        item => item.status === UploadFileStatus.Selected
      );
    
      for (const file of pendingUploadFiles) {
        // 先更新当前文件状态为上传中
        setFileList(prev => prev.map(item => 
          item.uid === file.uid ? {...item, status: UploadFileStatus.Uploading} : item
        ));
    
        try {
          const formData = new FormData();
          formData.append('file', file.getRawFile());
          // 调用自定义上传接口,同时传入需要写入数据库的元数据
          const uploadResult = await customUploadApi({
            file: formData,
            meta: { /* 你的元数据字段,比如关联业务id、上传人信息等 */ }
          });
    
          // 上传成功,更新状态为已上传,存储服务端返回的文件id供后续删除用
          setFileList(prev => prev.map(item => 
            item.uid === file.uid ? {
              ...item,
              status: UploadFileStatus.Uploaded,
              serverFileId: uploadResult.id
            } : item
          ));
        } catch (err) {
          // 上传失败,标记错误状态
          setFileList(prev => prev.map(item => 
            item.uid === file.uid ? {...item, status: UploadFileStatus.Error} : item
          ));
        }
      }
    };
    

避坑要点

  • 所有Upload的事件回调(onAdd/onRemove/onStatusChange)里,只要你要走自定义逻辑,第一时间调用e.preventDefault(),就能100%阻断组件内部的默认行为,不会出现隐式的请求触发
  • 不要给组件传saveUrl/removeUrl/saveHeaders/removeHeaders这类和默认请求相关的属性,从根源上杜绝默认请求的触发可能
  • 不要用组件内置工具栏里的上传按钮,自己在外部放按钮控制上传时机,避免意外触发组件内部的上传状态流转

内容的提问来源于stack exchange,提问作者pinale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:45:49