表单是应用中不可缺少的一部分,表单不同于其他 HTML 元素,因为它要响应用户的交互,并根据用户输入显示不同的状态。React 基于props和state的组件渲染机制,可以很好的处理表单的复杂性。在React 中,表单组件分为两种:受控组件和非受控组件。
1. 受控组件
1.1 受React控制的值
受控组件也被称做“受限组件”或“受约束组件”。受控组件与其它React组件行为一样,其所有状态属性的更改都由React 来控制,也就是说它根据组件的props和state来改变组件的UI表现形式。
对于一个<input>受限组件,当我们设置其value值。组件渲染后,其value值会始终保持不变:
var MyInput = React.createClass({
render: function() {
return <input type="text" value="niefengjun.cn" />;
}
});
ReactDOM.render(
<MyInput />,
document.getElementById('example')
);
上面的代码渲染后是一个值为niefengjun.cn的 input 元素,用户在渲染后的元素里中输入任何值都不起作用,这是因为其值是受React 控制的,React已经为其赋值为niefengjun.cn。
1.2 表单组件事件
React控制受控组件的值保持不变,同样其也会受组件状态的改变,其表现形式和普通React组件一样。而果想响应更新用户输入的值,可以使用React 组件事件设置状态(state或props)。
如,我们通过组件的 onChange 事件改变input的value:
var MyInput = React.createClass({
getInitialState: function() {
return {value: 'niefengjun.cn'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
return <input type="text" value={this.state.value} onChange={this.handleChange} />;
}
});
ReactDOM.render(
<MyInput />,
document.getElementById('example')
);
1.3 受控组件的好处
受控组件的优势在于,我们可以非常容易实现对用户输入的验证,或者对用户交互做额外的处理。
如,对用户输入做截断处理:
handleChange: function(event) {
this.setState({value: event.target.value.substr(0, 140)});
}
上面的代码会接受用户输入,并截取前 140 个字符
2. 非受控组件
2.1 反模式
非受控组件相对于普通React 组件或受控组件来说是一种反模式。非受控组件不受React 的状态控制(state或props)。
如,对于<input>来说,当我们不设置其value或设置为null时就是一个非受控组件。非受控的组件渲染出来的元素直接反应用户输入,其值会随用户输入的改变而改变:
var MyInput = React.createClass({
render: function() {
return <input type="text" />;
}
});
ReactDOM.render(
<MyInput />,
document.getElementById('example')
);
非受控组件依然可以设置初始值。如,我们可以<input>的defaultValue属性:
render: function() {
return <input type="text" defaultValue="niefengjun.cn" />;
}
2.2 非受控组件的事件
和受控组件一样,非受控组件同样可以使用React 组件事件。
如,我们可监听<input>的onChange事件:
var MyInput = React.createClass({
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
return <input type="text" defaultValue="niefengjun.cn" onChange={this.handleChange} />;
}
});
ReactDOM.render(
<MyInput />,
document.getElementById('example')
);
2.3 非受控组件的引用
非受控组件一般没什么用途,其值并非受父组件控制,它的值受其自身控制。但是,我们可以对其添加一个ref属性,这样可以获得对非受控组件渲染后底层DOM元素的访问。
3. 受控组件与非受控组件的选择
React 组件应当只受状态的改变而改变,虽然使用受控组件在代码量上有所增加,但推荐使用受控组件。受控组件的组件状态由React 控制,可以更好的控制数据流,在用户输入时能够更新组件状态。
在前面的<input>示例中,一个受控组件有如下过程:
- 通过
getInitialState设置defaultValue <input>渲染时设置默认值onChange事件触发后,调用相关处理器change事件处理更新state- 重新渲染
<input>
