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
相关产品推荐
相关产品推荐

