React Dropzone图片预览TypeScript代码报错求助
解决react-dropzone在TypeScript中实现文件预览的类型错误与ESLint警告
核心TypeScript错误修复
代码中TypeScript报错的根源是未给useState指定明确类型,初始空数组被推断为never[],导致后续访问file.name、file.preview时类型不匹配。
步骤1:定义扩展的文件类型接口
react-dropzone返回的文件是FileWithPath类型,我们需要给它添加自定义的preview属性,先定义接口:
import { FileWithPath } from 'react-dropzone'; interface PreviewFile extends FileWithPath { preview: string; }
步骤2:给useState指定类型
初始化files状态时明确指定类型为PreviewFile[]:
const [files, setFiles] = useState<PreviewFile[]>([]);
这样TypeScript就能正确识别数组中每个文件的属性,解决所有never类型相关报错。
ESLint警告修复
1. 移除未使用的代码
删掉所有导入但未使用的模块和变量:
- 移除
useCallback、useMemo、DropzoneState的导入 - 删除未使用的
styleDiv、style变量
2. 给img添加alt属性
根据无障碍要求,img元素必须有alt属性,这里用文件名作为描述:
<img src={file.preview} alt={file.name} onLoad={() => URL.revokeObjectURL(file.preview)} />
3. 修复useEffect依赖项
将files添加到useEffect的依赖数组中,避免陈旧闭包问题:
useEffect(() => { return () => files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files]);
完整修复后的代码
import { useEffect, useState } from 'react'; import { useDropzone, FileWithPath } from 'react-dropzone'; interface PreviewFile extends FileWithPath { preview: string; } function App() { const [files, setFiles] = useState<PreviewFile[]>([]); const { getRootProps, getInputProps } = useDropzone({ accept: { 'image/*': [] }, onDrop: (acceptedFiles: FileWithPath[]) => { setFiles(acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }))); } }); const thumbs = files.map(file => ( <div key={file.name}> <div> <img src={file.preview} alt={file.name} onLoad={() => URL.revokeObjectURL(file.preview)} /> </div> </div> )); useEffect(() => { return () => files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files]); return ( <section className="container"> <div {...getRootProps({ className: 'dropzone' })}> <input {...getInputProps()} /> <p>Drag 'n' drop some files here, or click to select files</p> </div> <aside> {thumbs} </aside> </section> ); } export default App;
内容的提问来源于stack exchange,提问作者musako
相关产品推荐
相关产品推荐

