React 非受控表单组件

表单元素不采用value-onChange/checked-onChange方式来对state区中的数据进行双向绑定,我们就说表单元素是非受控表单元素。
非受控表单元素需要使用<form></form>标记对。

一、非受控文本框

  1. 非受控文本框采用defaultValue来设置初始数据,defaultValue只能设置一次。
  2. <form>带有一个onSubmit事件,当表单中具有数据提交功能的按钮单击时,会自动执行这个事件。
  3. 非受控文本框中设置一个ref属性,在onSubmit事件中通过this.refs来获取文本框中用户输入的内容。
<form onSubmit={()=>this.search(event)}>
	<div className="form-group">
		<label>产品:</label>
		<input ref="product" type="text" defaultValue="默认值" className="form-control" />
	</div>
	<div className="form-group">
		<button type="submit" className="btn btn-success">搜索</button>
	</div>
</form>


//表单的onSubmit事件
search(event){
    //this.refs:ref属性在表单元素中的取值:表单元素的DOM节点对象
    let {product,searchEngine,upload} = this.refs; //只要是对象,都可以通过匹配模式的方式进行解构
    event.preventDefault(); //取消表单默认提交行为
    console.log(this.refs.product.value);	//解构前
    console.log(product.value);	//结构后
}

二、非受控select菜单

  1. 非受控<select>菜单的处理方式和非受控文本框的处理方式一致。
  2. 在表单的onSubmit事件中,this.refs是一个存储了所有利用ref属性进行命名的节点的对象。
constructor(props){
	super(props);
	this.state = {
		engine:['百度','搜狗','360搜索','Google']
	}
}


<form onSubmit={()=>this.search(event)}>
	<div className="form-group">
	<label>搜索引擎:</label>
		<select ref="searchEngine" className="form-control">
		{
			this.state.engine.map((item,index)=>{
				return(
					<option value={item} key={index}>{item}</option>
				)
			})
		}
		</select>
	</div>
</form>


//表单的onSubmit事件
search(event){
	console.log(this.refs);    // {ref属性在表单元素中的取值:表单元素的DOM节点对象}
}

三、文件域

  1. React中的文件域都是非受控的,没有受控的文件域。
  2. 通过文件域的ref属性可以得到文件域的DOM节点,在借助H5中有关FileListFile类的属性进行操作。
//表单的onSubmit事件
search(event){
    //this.refs:ref属性在表单元素中的取值:表单元素的DOM节点对象
    let {product,searchEngine,upload} = this.refs; //只要是对象,都可以通过匹配模式的方式进行解构
    event.preventDefault(); //取消表单默认提交行为
    if(upload.files.length == 0){
        alert('请选择上传的文件')
    }else{
        console.log(upload.files);  //FilesList类
        console.log(upload.files.item(0));  //File类
        let file = upload.files.item(0);
        let reg = /^image\/(jpg|jpeg|png|gif)$/;
        console.log(file.type);  //用户上传文件的MIME类型
        if(reg.test(file.type)){
            let blob = window.URL.createObjectURL(file);	//获取图片的blob地址
            this.setState({
                imgUrl:blob
            })
        }else{
            alert('请选择图片格式的文件')
        }
    }
}
### 受控组件的缺点 受控组件React 中虽然提供了一种更接近传统 HTML 表单行为的方式来处理表单数据,但其存在一些显著的局限性。 首先,受控组件的状态不由 React 的 `state` 管理,而是由 DOM 自身控制。这意味着当需要对输入值进行实时验证、格式化或依赖状态的其他操作时,会变得常困难。React 推荐使用受控组件来实现这些功能,因为只有通过 `state` 才能确保组件的行为是可预测和一致的[^1]。 其次,由于受控组件不依赖 React 的状态机制,因此它们无法利用 React 提供的数据流优势。例如,在父子组件之间传递数据、更新 UI 或与其他状态管理工具(如 Redux)集成时,受控组件的表现可能不如受控组件直观和高效[^4]。 再者,使用 `ref` 来访问受控组件的值可能导致代码复杂度增加,并且容易引发副作用。这种方式违背了 React 的声明式编程范式,使得调试和维护变得更加繁琐[^3]。 此外,受控组件难以支持复杂的交互逻辑,比如动态表单验证、多步骤表单导航或基于用户输入的条件渲染等场景。这些都需要一个集中管理和更新的状态源,而这正是受控组件所缺乏的特性之一[^2]。 最后,在团队协作环境中,使用受控组件可能会导致开发人员之间的理解差异,尤其是对于那些习惯于 React 声明式风格的开发者来说,这种直接操作 DOM 的方式显得不够“React”[^5]。 综上所述,尽管受控组件适用于某些特定情况下的快速开发,但在大多数现代 React 应用程序中,推荐优先考虑使用受控组件以获得更好的可维护性和一致性。 --- ```jsx function UncontrolledInputExample() { const inputRef = React.useRef(null); const handleSubmit = (e) => { e.preventDefault(); console.log('受控组件的值:', inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={input.ref} /> <button type="submit">提交</button> </form> ); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值