文件上传时需注意清空 input 的 value 值
问题描述
在 React 中使用 input type="file" 进行文件上传时,如果用户重复上传同一个文件,会发现第二次上传无法触发 onChange 事件。这是因为 input 的 value 值没有被清空,导致 React 认为文件没有发生变化。
解决方案
在触发文件选择框之前,需要先清空 input 的 value 值。
代码示例
jsx
// 文件输入框的引用
const fileInputRef = useRef(null);
// 处理文件选择变化
const handleFileInputChange = (e) => {
const fileList = [...e.target.files];
handlerFiles(fileList); // 处理选中的文件
};
// 处理上传按钮点击
const handleUploadIconClick = () => {
// 重要:清空 input 的 value,确保相同文件可以重复上传
fileInputRef.current.value = '';
fileInputRef.current.click();
};
// JSX 部分
<input
ref={fileInputRef}
type="file"
multiple
style={{ display: "none" }}
onChange={handleFileInputChange}
accept=".jpg, .jpeg, .png, .obj, .fbx, .gltf, .glb, .dae, .ply, .stl, .heic"
/>注意事项
- 必须在触发文件选择前清空
input的value - 使用
ref来获取input元素的引用 - 可以通过
style={ display: "none" }隐藏原生文件选择框 multiple属性允许选择多个文件accept属性用于限制可选择的文件类型
最佳实践
- 为了更好的用户体验,建议添加文件类型验证
- 可以添加文件大小限制
- 建议添加上传进度提示
- 处理上传错误的情况
扩展示例
jsx
const handleFileInputChange = (e) => {
const fileList = [...e.target.files];
// 文件验证
const validFiles = fileList.filter(file => {
// 文件大小限制(例如:10MB)
const isValidSize = file.size <= 10 * 1024 * 1024;
// 文件类型验证
const validTypes = ['image/jpeg', 'image/png'];
const isValidType = validTypes.includes(file.type);
return isValidSize && isValidType;
});
if (validFiles.length !== fileList.length) {
alert('某些文件不符合要求,已被过滤');
}
handlerFiles(validFiles);
};这样的文件上传处理方式更加健壮和用户友好。记住,清空 input 的 value 值是处理文件重复上传的关键所在。