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

如何在React中为Uploadthing创建自定义按钮或拖拽上传区域?

UploadThing 自定义上传组件与useUploadThing使用指南

一、useUploadThing 的正确导入方式

useUploadThing 是从 UploadThing 的 React 包中导出的,标准导入路径如下:

import { useUploadThing } from "@uploadthing/react";

二、自定义上传按钮组件

基于 useUploadThing 提供的 startUpload 方法,你可以完全自定义上传按钮的样式与交互逻辑,示例代码如下:

import { useUploadThing } from "@uploadthing/react";

function CustomUploadButton() {
  const { startUpload, isUploading } = useUploadThing("myUploadEndpoint", {
    onClientUploadComplete: () => {
      alert("上传成功!");
    },
    onUploadError: () => {
      alert("上传出错了!");
    },
  });

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = e.target.files;
    if (selectedFiles) startUpload(Array.from(selectedFiles));
  };

  return (
    <div>
      {/* 隐藏原生文件选择框 */}
      <input
        type="file"
        onChange={handleFileSelect}
        disabled={isUploading}
        style={{ display: "none" }}
        id="custom-file-input"
      />
      {/* 自定义触发按钮 */}
      <label htmlFor="custom-file-input">
        <button 
          disabled={isUploading}
          style={{
            padding: "8px 16px",
            backgroundColor: isUploading ? "#ccc" : "#2563eb",
            color: "white",
            border: "none",
            borderRadius: "4px",
            cursor: isUploading ? "not-allowed" : "pointer"
          }}
        >
          {isUploading ? "上传中..." : "选择文件上传"}
        </button>
      </label>
    </div>
  );
}

三、自定义拖拽上传区域

同样基于 useUploadThing,可以实现自定义拖拽上传区域,示例如下:

import { useUploadThing } from "@uploadthing/react";

function CustomUploadDropzone() {
  const { startUpload, isUploading } = useUploadThing("myUploadEndpoint", {
    onClientUploadComplete: () => {
      alert("上传成功!");
    },
    onUploadError: () => {
      alert("上传出错了!");
    },
  });

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    const droppedFiles = Array.from(e.dataTransfer.files);
    if (droppedFiles.length) startUpload(droppedFiles);
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
  };

  return (
    <div
      onDrop={handleDrop}
      onDragOver={handleDragOver}
      style={{
        border: isUploading ? "2px solid #ccc" : "2px dashed #666",
        padding: "2rem",
        borderRadius: "8px",
        textAlign: "center",
        cursor: "pointer",
        backgroundColor: isUploading ? "#f5f5f5" : "white"
      }}
    >
      {isUploading ? (
        <p>上传中,请稍候...</p>
      ) : (
        <>
          <p>拖拽文件到这里,或者点击选择文件</p>
          <input
            type="file"
            multiple
            onChange={(e) => {
              const selectedFiles = e.target.files;
              if (selectedFiles) startUpload(Array.from(selectedFiles));
            }}
            style={{ display: "none" }}
            id="dropzone-file-input"
          />
          <label 
            htmlFor="dropzone-file-input" 
            style={{ 
              color: "#2563eb",
              textDecoration: "underline",
              cursor: "pointer"
            }}
          >
            点击选择文件
          </label>
        </>
      )}
    </div>
  );
}

关键注意事项

  • 确保后端已正确配置 myUploadEndpoint 对应的上传端点,否则上传请求会失败。
  • isUploading 状态可用于控制按钮禁用、显示加载动画,优化用户体验。
  • 你可以完全自定义组件样式,比如修改颜色、尺寸、布局,适配项目设计体系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:15:16