自定义实现图片上传组件,主要是跟着MDN官方文档实现。onChange事件在第二次上传同样的文件时不会触发。React环境 + 单个图片上传
发现问题:
当上传不同的图片时,事件触发正常,但是上传刚刚上传过的图片,事件不触发。
分析问题:
onChange事件的触发标准是value值发生变化。所以每次操作完需要将value值清空。
解决问题:
fileRef.current.value = "";
// 如果是原生实现,则是 document.getElementById("image_uploads").value = "";
PS: 网上同类原生实现的解决方案replaceWith👎
document.getElementById("image_uploads").replaceWith(<input type="file" />)
其原理本质上是将原来的DOM组件换成一个新的,没必要。
1. 替换的时候还有方法
2. React中该方案鸡肋
完整实现代码:
html代码
<div className="image_upload_container">
<label id="upload_button" htmlFor="image_uploads">
<i className="iconfont icon-a-danchuang-shangchuantupian"></i>
<span>上传</span>
<input ref={fileRef} onChange={uploadFile} accept={fileType || ".jpg, .gif, .png"} type="file" id="image_uploads" />
</label>
<div className="preview" ref={previewRef}>
</div>
</div>
对应方法:
const uploadFile = (e) => {
removeAllPreview(); // 绘制蒙层+删除;
const mask = document.createElement("div");
mask.className = "mask";
const icon = document.createElement("i");
icon.className = "iconfont icon-biaoge-shanchu";
icon.addEventListener("click", () => {
e.stopPropagation();
removeAllPreview();
if (fileRef.current) {
fileRef.current.value = "";
}
});
mask.appendChild(icon); // // 绘制图片;
const curFile = fileRef.current && fileRef.current.files;
const image = document.createElement("img");
image.src = URL.createObjectURL(curFile[0]);
previewRef.current.appendChild(image);
previewRef.current.appendChild(mask);
if (curFile[0] && curFile[0].size > maxSize) {
sizeRef.current.innerHTML = "图片尺寸不能超过" + (maxSize/(1024*1024)).toFixed(3) + "M";
} // 将文件值传递给外界
handleFile(curFile[0]);
};