React自定义实现多文件上传组件问题背景 通过label模拟按钮。然后使用useState渲染文件列表 问题现象 当一
用React自定义实现多文件上传组件,且展示文件列表
问题背景
通过label模拟按钮。然后使用useState渲染文件列表
const FileUpload = (props) => {
const { fileType, handleFile } = props;
const [fileList, setFileList] = useState([]);
const uploadFile = (e) => {
setFileList(e.target.files);
handleFile && handleFile(e.target.files);
};
const handleClose = (item) => {
const leftFiles = Array.prototype.filter.call(fileList, (i) => {
return i.name !== item.name;
});
setFileList(leftFiles);
handleFile(leftFiles);
};
return (
<div className="multiple_file_box">
<div className="mulfile_upload_container">
<label id="multifile_upload_button" htmlFor={`multifile_uploads`}>
<span><img src={UploadImage} />选择文件</span>
<input id={`multifile_uploads`} multiple onChange={uploadFile} accept={fileType || "*"} type="file" />
</label>
<div className="multifile_preview" >
{
Array.from(fileList).map(item => {
return (
<div className="multifile_item" key={item.lastModified}>
<span>{item.name}</span>
<span className="file_close" onClick={() => handleClose(item)}></span>
</div>
);
})
}
</div>
</div>
</div> );};
问题现象
当一个页面同时存在二个和二个以上的组件时,不论点击哪个组件按钮,渲染的列表都渲染到第一个组件的列表中。
问题定位
1. 将同样的事件添加到input="text"
中时,不会出现问题,可以确认是type="file"
的问题。
2. 将id改为非固定值,问题消失。
由此可知,问题出现的原因只是因为type="file"
的onChange
触发,跟id密切相关,虽然id处于不同的容器中,也会查找浏览器中出现的第一个id值。不会在最近的容器中寻找。
解决方案
将id值改为唯一值,使用uuid值。(可查看如何获取uuid)
```
<label id="multifile_upload_button" htmlFor={`multifile_uploads_${uuid}`}>
<span><img src={UploadImage} />选择文件</span>
<input id={`multifile_uploads_${uuid}`} multiple onChange={uploadFile} accept={fileType || "*"} type="file" />
</label>
```
转载自:https://juejin.cn/post/7008130365969661988