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

React+TypeScript中基于react-dropzone实现全屏拖放及图片预览

实现全屏拖放区域与图片预览的修改方案

针对你的需求,以下是修改后的代码及关键改动说明:

核心改动点

  • 全屏拖放区域:将拖放根元素绑定到占满屏幕的容器,通过样式实现全屏覆盖,同时居中显示操作提示
  • 优化图片预览:调整预览布局,修复样式错误,添加卡片式预览效果,让图片自适应显示
  • 内存泄漏修复:修正useEffect依赖,确保文件更新时及时清理ObjectURL
  • 交互反馈优化:添加拖放状态的视觉提示,提升用户体验
import { useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone';

function App() {
  const [files, setFiles] = useState<(File & { preview: string })[]>([]);
  
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    accept: {
      'image/*': []
    },
    onDrop: acceptedFiles => {
      // 追加新文件(若需覆盖原有文件,直接替换为setFiles(acceptedFiles.map(...))即可)
      setFiles(prev => [
        ...prev,
        ...acceptedFiles.map(file => ({
          ...file,
          preview: URL.createObjectURL(file)
        }))
      ]);
    }
  });

  // 生成预览卡片
  const previewCards = files.map(file => (
    <div key={file.name} className="bg-white rounded-xl shadow p-4">
      <div className="mb-2">
        <img
          src={file.preview}
          onLoad={() => URL.revokeObjectURL(file.preview)}
          alt={file.name}
          className="max-w-[300px] max-h-[200px] object-contain rounded"
        />
      </div>
      <p className="text-sm text-gray-600">{file.name}</p>
      <input 
        placeholder="添加备注"
        className="w-full mt-2 bg-gray-100 rounded-lg border border-gray-300 p-2" 
      />
    </div>
  ));

  useEffect(() => {
    // 清理所有ObjectURL,防止内存泄漏
    return () => files.forEach(file => URL.revokeObjectURL(file.preview));
  }, [files]); // 添加files作为依赖,确保文件更新时触发清理

  return (
    <section 
      {...getRootProps({
        className: `h-screen w-screen flex flex-col items-center justify-center p-4 transition-colors ${isDragActive ? 'bg-gray-200' : 'bg-gray-50'}`
      })}
    >
      <input {...getInputProps()} />
      {/* 拖放提示文字 */}
      <div className="text-center mb-8">
        <p className="text-xl font-medium">
          {isDragActive ? '松开鼠标完成上传' : '拖拽图片到任意区域,或点击选择文件'}
        </p>
        <p className="text-gray-500 mt-2">支持所有图片格式</p>
      </div>
      {/* 预览区域 */}
      <div className="flex flex-wrap gap-4 justify-center w-full max-w-6xl">
        {previewCards}
      </div>
    </section>
  );
}

export default App;

补充说明

  • 预览图的尺寸可通过调整max-w-[300px] max-h-[200px]参数修改
  • 若不需要保留历史上传的文件,可将onDrop中的追加逻辑改为直接覆盖
  • 拖放状态的背景色切换通过isDragActive状态实现,增强交互感知

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:15:38