在 React 中表单组件可分为两类,受控与非受控组件.

一、 受控组件

设置了 value 的 <input> 是一个受控组件。 对于受控的 <input>,渲染出来的 HTML 元素始终保持 value 属性的值。例如:

render() {
return <input type="text" value="Hello"/>
}

上面的代码将渲染出一个值为 Hello! 的 input 元素。用户在渲染出来的元素里输入任何值都不起作用,因为 React 已经赋值为 Hello!。如果想响应更新用户输入的值,就得使用 onChange 事件:

 constructor(props) {
super(props);
this.state={value:'Hello'};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}

上面的代码中,React 将用户输入的值更新到 <input> 组件的 value 属性。这样实现响应或者验证用户输入的界面就很容易了。
注意:如果将value指定为undefined,则其变为了非受控组件,可以允许用户随意输入。

二、 非受控组件

没有设置 value(或者设为 null) 的 <input> 组件是一个非受控组件。对于非受控的 <input> 组件,渲染出来的元素直接反映用户输入。例如:

render() {
return <input type="text"/>
}

上面的代码将渲染出一个空值的输入框,用户输入将立即反应到元素上。和受控元素一样,使用 onChange 事件可以监听值的变化。

如果想给组件设置一个非空的初始值,可以使用 defaultValue 属性。例如:

render() {
return <input type="text" defaultValue="Default Value">
}

上面的代码渲染出来的元素和受控组件一样有一个初始值,但这个值用户可以改变并会反应到界面上。同样地, 类型为 radiocheckbox 的<input> 支持 defaultChecked 属性, <select> 支持 defaultValue 属性。

 render() {
return (
<div>
<input type="radio" name="opt" defaultChecked /> Option 1
<input type="radio" name="opt" /> Option 2
<select defaultValue="C">
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
</div>
);
}

需要注意的是,默认值只适用于第一次渲染,在重渲染阶段将不会适用。

三、checkbox和radio

checkbox 和 radio 比较特殊, 如果在 onChange 事件中调用了 preventDefault ,那么浏览器不会更新 checked 状态,即便事实上组件的值已经 checked 或者 unchecked 了 。

class HelloWorld extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.state={checked:true};
}
handleChange(e){
e.preventDefault();
this.setState((prevState) => {
return {checked:!prevState.checked};
});
}
render(){
return (<div>
<input type="checkbox" checked={this.state.checked} onChange={this.handleChange} />点击我
<br/>{String(this.state.checked)}
</div>)
}
} ReactDOM.render(<HelloWorld/>,document.body);

在上面的例子中,虽然this.state.checked的值已经改变,但是checkbox的值确没有变,解决这个问题有三种方法:

1) 避免调用e.preventDefault,比如将上例的e.preventDefault注释掉就可以了;

2) 在setTimeout中处理checked的修改

handleChange(e){
window.setTimeout(() => {
this.setState((prevState) => {
return {checked:!prevState.checked};
});
},0);
}

3) 使用click事件

受控组件 & 非受控组件的更多相关文章

  1. Vue 中的受控与非受控组件

    Vue 中的受控与非受控组件 熟悉 React 的开发者应该对"受控组件"的概念并不陌生,实际上对于任何组件化开发框架而言,都可以实现所谓的受控与非受控,Vue 当然也不例外.并且 ...

  2. 七天接手react项目 —— 生命周期&受控和非受控组件&Dom 元素&Diffing 算法

    生命周期&受控和非受控组件&Dom 元素&Diffing 算法 生命周期 首先回忆一下 vue 中的生命周期: vue 对外提供了生命周期的钩子函数,允许我们在 vue 的各个 ...

  3. 浅谈React受控与非受控组件

    背景 React内部分别使用了props, state来区分组件的属性和状态.props用来定义组件外部传进来的属性, 属于那种经过外部定义之后, 组件内部就无法改变.而state维持组件内部的状态更 ...

  4. React学习之受控和非受控组件

    受控组件是通过事件完成对元素value的控制,反之就是非受控组件. 1.受控组件的value通过onChange事件来改变,非受控不需要通过事件来改变value. 2.受控组件通过事件通过setSta ...

  5. react 表单受控和非受控

    参见:https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/ 非受控: onSubmit = ()=>{ const val ...

  6. 【vue】父组件主动调用子组件 /// 非父子组件传值

    一  父组件主动调用子组件: 注意:在父组件使用子组件的标签上注入ref属性,例如: <div id="home"> <v-header ref="he ...

  7. Vue兄弟组件(非父子组件)状态共享与传值

      前言:网上大部分文章写的有点乱,很少有讲得易懂的文章. 所以,我写了篇在我能看得懂的基础上又照顾到大家的文章 =.= 作者:X1aoYE 备注:此文原创,转载请注明~  内容里的<br> ...

  8. Vue 组件 非父子组件通信

    有时候两个组件也需要通信(非父子关系),在简单的场景下,可以使用一个空的vue实例作为中央事件总线: var bus = new Vue(); //触发组件a中的事件 bus.$emit('id-se ...

  9. React:受控组件与非受控组件混用实战 - 译文

    原文链接:React: hybrid controlled components in action 受控组件 非受控组件 混用受控组件和非受控组件 原则一 原则二 原则三 原则四 实施方案 总结 F ...

随机推荐

  1. Python 可变类型和不可变类型,以及其引用

    基本数据类型的引用        在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址.访问这块内存需要用到变量名,变量名实际存储的是变量的 ...

  2. 基于LSTM对西储大学轴承故障进行分析

    这篇文章是小萌新对西储大学轴承故障进行分析,固定特征为故障直径为0.007,电机转速为1797,12k驱动端故障数据(Drive_End)即DE-time.故障类型y值:滚动体故障,内圈故障,3时,6 ...

  3. NOIP模拟 9.09

    AK300分 果实计数 (count.pas/.c/.cpp) 时间限制:1s,空间限制32MB 题目描述: 淘淘家有棵奇怪的苹果树,这棵树共有n+1层,标号为0~n.这棵树第0层只有一个节点,为根节 ...

  4. Leetcode77. Combinations组合

    给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3] ...

  5. 如何查看MySQL执行计划呢?

    覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引称为 覆盖索引(Covering Index) 如果要使用覆盖索引,一定 ...

  6. oracle -视图 序列 约束

    1.视图 视图是基于一个或者多个表数据库对象,视图允许用户创建一个无数据的”伪表“,视图只是一个获取特定列好行的sql查询组成,通过视图检索数据就像从表中检索数据 一样. 视图可以提供一个附加的安全层 ...

  7. pycharm多行批量缩进和反向缩进快捷键

    在 VS, PYCHARM 中只要 拉选块之后,按下tab键,整个块就会缩进 按下 shift + tab 就会反向缩进

  8. Docker.[4].容器操作.

    Docker.[4].容器操作. 熟悉的指令: 启动容器 docker run 交互式启动容器 docker run -i -t IMAGENAME /bin/bash 停止容器 exit 停止容器 ...

  9. 【JZOJ4934】【NOIP2017GDKOI模拟1.12】a

    helpless fucking 结论:如果一个数可以被对于a序列中每个数的最大公约数整除,那么它就是好的. Bitch Man 感性证明: 贪心地想,对于a序列中的任意两个数,它们的最大公约数可由这 ...

  10. ELK之elasticsearch安装&&kibana安装

    1.ES和Kibana安装都是开箱即用的? 解压缩就可以用 elasticsearch解压缩之后,双击下图中的elasticsearch.bat,启动,kibana也是一样 双击之后, 我们看到上图有 ...