React-Redux中如何重置文件输入框?表单重置时文件字段未清空
解决React-Redux Form重置时文件字段不清空的问题
我之前也碰到过一模一样的情况——react-redux-form的默认重置逻辑确实不会处理文件输入字段,这是因为文件输入的value属性是只读的,框架没法通过常规表单重置去修改它。不过我们可以结合Redux的重置Action和手动操作DOM来搞定这个问题,具体步骤如下:
1. 给文件输入组件添加DOM引用
不管你用类组件还是函数组件,都需要先拿到文件输入的DOM节点引用,这样才能手动清空它的内容:
类组件写法
<ReactBootstrap.FormGroup> <ReactBootstrap.ControlLabel>上传文件</ReactBootstrap.ControlLabel> <ReactBootstrap.FormControl type="file" model="user.file" ref={(input) => { this.fileInput = input; }} // 保存DOM节点引用 /> </ReactBootstrap.FormGroup>
函数组件写法(用useRef)
import { useRef } from 'react'; // ... const fileInputRef = useRef(null); <ReactBootstrap.FormGroup> <ReactBootstrap.ControlLabel>上传文件</ReactBootstrap.ControlLabel> <ReactBootstrap.FormControl type="file" model="user.file" ref={fileInputRef} // 保存DOM节点引用 /> </ReactBootstrap.FormGroup>
2. 自定义重置函数,同时处理Redux Store和DOM
别依赖表单的默认重置按钮,自己写一个重置函数:先调用react-redux-form的reset Action清空Store里的表单数据,再手动清空文件输入的DOM内容:
类组件写法(需连接Redux)
import { reset } from 'react-redux-form'; import { connect } from 'react-redux'; class UserForm extends Component { handleReset = () => { // 第一步:重置Redux Store中的表单数据 this.props.dispatch(reset('user')); // 第二步:手动清空文件输入的DOM值 if (this.fileInput) { this.fileInput.value = ''; } }; render() { return ( <Form model="user" component={Forms} validators={{ gender:{required:val=>required(val)}, '': {passwordsMatch: (vals) => required(vals.confpwd) ? vals.pwd === vals.confpwd : true } }} onSubmit={v =>this.handleSubmit(v)} > {/* 其他表单字段... */} {/* 文件字段... */} <button type="button" onClick={this.handleReset}>重置所有字段</button> <button type="submit">提交</button> </Form> ); } } // 连接Redux,让组件能dispatch Action export default connect()(UserForm);
函数组件写法(用useDispatch)
import { useDispatch } from 'react-redux'; import { reset } from 'react-redux-form'; function UserForm() { const dispatch = useDispatch(); const fileInputRef = useRef(null); const handleReset = () => { // 重置Redux Store中的表单数据 dispatch(reset('user')); // 清空文件输入的DOM值 if (fileInputRef.current) { fileInputRef.current.value = ''; } }; return ( <Form model="user" component={Forms} validators={{ gender:{required:val=>required(val)}, '': {passwordsMatch: (vals) => required(vals.confpwd) ? vals.pwd === vals.confpwd : true } }} onSubmit={v =>handleSubmit(v)} > {/* 其他表单字段... */} {/* 文件字段... */} <button type="button" onClick={handleReset}>重置所有字段</button> <button type="submit">提交</button> </Form> ); }
为什么要这么做?
文件输入控件是个特殊存在:它的value属性是只读的,react-redux-form的默认重置逻辑只能更新Redux Store里的状态,但没法直接修改DOM上的文件输入值。所以必须手动清空DOM的value,才能让用户直观看到文件输入已重置,同时确保下次选择文件时能正常触发change事件。
内容的提问来源于stack exchange,提问作者Pranab V V
相关产品推荐
相关产品推荐

