React自定义实现多文件上传组件

·  阅读 804
React自定义实现多文件上传组件

用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>
```
复制代码
分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改