一、受控组件html
在HTML当中,像<input>
,<textarea>
, 和 <select>
这类表单元素会维持自身状态,并根据用户输入进行更新。但在React中,可变的状态一般保存在组件的状态属性中,而且只能用 setState()
方法进行更新。react
咱们经过使react变成一种单一数据源的状态来结合两者。React负责渲染表单的组件仍然控制用户后续输入时所发生的变化。相应的,其值由React控制的输入表单元素称为“受控组件”。segmentfault
因为 value
属性是在咱们的表单元素上设置的,所以显示的值将始终为 React数据源上this.state.value
的值。因为每次按键都会触发 handleChange
来更新当前React的state,所展现的值也会随着不一样用户的输入而更新。bash
<input type="text" value={this.state.value} onChange={this.handleChange} />复制代码
二、非受控组件架构
要编写一个非受控组件,而非为每一个状态更新编写事件处理程序,你能够 使用 ref 从 DOM 获取表单值。
dom
在 React 的生命周期中,表单元素上的 value
属性将会覆盖 DOM 中的值。使用非受控组件时,一般你但愿 React 能够为其指定初始值,但再也不控制后续更新。要解决这个问题,你能够指定一个 defaultValue
属性而不是 value
。
性能
<input type="text" defaultValue={'1232'} ref={this.input} />复制代码
举例:ui
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.input = React.createRef();
this.state = {
value:'567'
}
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
handleChange(e){
this.setState({value: e.target.value});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" defaultValue={'1232'} ref={this.input} />
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);复制代码
在 CodePen 上尝试。
this
三、对比受控组件和非受控组件spa
将输入的字母转化为大写展现
<input
type="text"
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value.toUpperCase(),
});
}}
/>复制代码
直接展现输入的字母
<input
type="text"
defaultValue={this.state.value}
/>复制代码
a、性能上的问题
在受控组件中,每次表单的值发生变化,都会调用一次onChange事件处理器,这确实会带来性能上的的损耗,虽然使用费受控组件不会出现这些问题,但仍然不提倡使用非受控组件,这个问题能够经过Flux/Redux应用架构等方式来达到统一组件状态的目的.
b、是否须要事件绑定
使用受控组件须要为每个组件绑定一个change事件,而且定义一个事件处理器来同步表单值和组件的状态,这是一个必要条件.固然,某些状况可使用一个事件处理器来处理多个表单域
import React, { Component } from 'react';
class Controlled extends Component {
constructor(...args) {
super(...args);
this.state = {
name: 'xiaoming',
age: 18,
};
}
handleChange = (name, e) => {
const { value } = e.target;
this.setState({
[name]: value,
});
}
render() {
const { name, age } = this.state;
return (
<div>
<input type="text" value={name} onChange={this.handleChange.bind(this, 'name')} />
<input type="text" value={age} onChange={this.handleChange.bind(this, 'age',)} />
</div>
);
}
}
export default Controlled;复制代码
参考:
https://segmentfault.com/a/1190000012404114#articleHeader2
https://react.docschina.org/docs/uncontrolled-components.html