受控组件
<input
type="text"
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value
});
}}
/>
<input>
或<select>
都要绑定一个change
事件,每当表单的状态发生变化,都会被写入组件的state
中,这种组件在React
中被称为受控组件。在受控组件中,组件渲染出的状态与它的value
消除了组件的局部状态,使得应用的整个状态可控。react
官方同样推荐使用受控表单组件,总结下React
受控组件更新state
的流程:
- 可以通过初始
state
中设置表单的默认值 - 每当表单的值发生变化时,调用
onChange
事件处理器 - 事件处理器通过合成事件对象
e
拿到改变后的状态,并更新应用的state
setState
触发视图的重新渲染,完成表单组件值得更新
非受控组件
<input type="text" />
<input type="text" defaultValue="BeiJing" />
- 一个表单没有
value
(单选按钮和复选按钮对应的是checked
),就可以称为非受控组件 - 使用
defaultValue
和defaultChecked
来表示组件的默认状态 - 通过
defaultValue
和defaultChecked
来设置组件的默认值,它仅会被渲染一次,在后续的渲染时并不起作用
对比受控组件和非受控组件
将输入的字母转化为大写展示
<input
type="text"
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value.toUpperCase(),
});
}}
/>
直接展示输入的字母
<input
type="text"
defaultValue={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value.toUpperCase(),
});
}}
/>
性能上的问题
在受控组件中,每次表单的值发生变化,都会调用一次onChange
事件处理器,这确实会带来性能上的的损耗,虽然使用费受控组件不会出现这些问题,但仍然不提倡使用非受控组件,这个问题可以通过Flux/Redux
应用架构等方式来达到统一组件状态的目的。
是否需要事件绑定
使用受控组件需要为每一个组件绑定一个change
事件,并且定义一个事件处理器来同步表单值和组件的状态,这是一个必要条件,当然,某些情况可以使用一个事件处理器来处理多个表单域。
import React, { Component } from 'react';
class Controlled extends Component {
constructor(...args) {
super(...args);
this.state = {
name: 'xingxing',
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;
表单组件的几个重要属性
状态属性
React
的form
组件提供了几个重要的属性,用来显示组件的状态:
- value: 类型为
text
的input
组件,textarea
组件以及select
组件都借助value
来展示应用的状态 - checked: 类型为
radio
或checkbox
的组件借助值为boolean
类型的selected
来展示应用的状态 - selected: 该属性可作用于
select
组件下面的option
上,React
并不建议这种方式表示状态,而推荐在select
组件上使用value
的方式
事件属性
当状态属性改变时会触发onChange
事件属性,受控组件中的change
事件与HTML DOM
中提供的input
事件更为类似。