React自定义UploadFile组件第二次触发onChange时props.files不更新问题
问题排查及修复方案
存在的问题
- 语法错误1:子组件
UploadFile的返回值错误使用了大括号{},React组件返回JSX应该用小括号(),当前写法相当于返回对象,会直接触发渲染报错。 - 语法错误2:函数定义语法错误,不管是子组件的
filesFunction还是父组件的handleFilesChange,都缺少箭头函数的箭头标识,正确的变量式函数定义格式为const fn = (参数) => {}。 - 属性覆盖错误:
Form.Control上重复定义了两次onChange属性,后定义的onChange={filesFunction(files)}会覆盖父组件传入的props.handleFilesChange,导致父组件的状态更新逻辑根本不会执行。 - 事件绑定错误:
onChange={filesFunction(files)}属于直接执行函数,不是事件回调绑定,组件首次渲染时就会直接调用filesFunction,且此处引用的files变量在子组件作用域内根本不存在。 - 状态更新逻辑问题:
e.target.files是浏览器原生的只读FileList类数组对象,直接保存这个对象到React状态中,React的浅比较逻辑会认为两次传入的FileList是同一个引用(哪怕选择了新文件),不会触发子组件的重渲染,自然就不会打印新的props.files。 - 可选优化点:input type="file"元素如果不手动重置
value属性,选择同名称文件时不会触发onChange事件,可以在处理完文件逻辑后手动重置。
修复后的代码
子组件 UploadFile
const UploadFile = (props) => { // 其他逻辑 console.log(props.files); const filesFunction = (filesInput) => { // 处理filesInput逻辑 } return ( <Form.Group controlId="formFileMultiple" className="mb-3"> <Form.Label> 文件 </Form.Label> <Form.Control type="file" multiple onChange={(e) => { props.handleFilesChange(e); filesFunction(e.target.files); }} name="files" /> </Form.Group> ) }
父组件调用逻辑
const [listOfFiles, setListOfFiles] = useState([]); const handleFilesChange = (e) => { // 将FileList转为普通数组保存,触发React状态更新 const files = Array.from(e.target.files); setListOfFiles(files); // 可选:重置input value,解决同文件二次选择不触发事件的问题 e.target.value = ''; } <UploadFile handleFilesChange={handleFilesChange} files={listOfFiles} />
内容的提问来源于stack exchange,提问作者penguin
相关产品推荐
相关产品推荐

