表单是应用中不可缺少的一部分,表单不同于其他 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="itbilu.com" />; } }); ReactDOM.render( <MyInput />, document.getElementById('example') );
上面的代码渲染后是一个值为itbilu.com
的 input 元素,用户在渲染后的元素里中输入任何值都不起作用,这是因为其值是受React 控制的,React已经为其赋值为itbilu.com
。
1.2 表单组件事件
React控制受控组件
的值保持不变,同样其也会受组件状态的改变,其表现形式和普通React组件一样。而果想响应更新用户输入的值,可以使用React 组件事件设置状态(state
或props
)。
如,我们通过组件的 onChange 事件改变input的value
:
var MyInput = React.createClass({ getInitialState: function() { return {value: 'itbilu.com'}; }, 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="itbilu.com" />; }
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="itbilu.com" onChange={this.handleChange} />; } }); ReactDOM.render( <MyInput />, document.getElementById('example') );
2.3 非受控组件的引用
非受控组件
一般没什么用途,其值并非受父组件控制,它的值受其自身控制。但是,我们可以对其添加一个ref
属性,这样可以获得对非受控组件
渲染后底层DOM元素的访问。
3. 受控组件与非受控组件的选择
React 组件应当只受状态的改变而改变,虽然使用受控组件
在代码量上有所增加,但推荐使用受控组件
。受控组件的组件状态由React 控制,可以更好的控制数据流,在用户输入时能够更新组件状态。
在前面的<input>
示例中,一个受控组件有如下过程:
- 通过
getInitialState
设置defaultValue <input>
渲染时设置默认值onChange
事件触发后,调用相关处理器change
事件处理更新state
- 重新渲染
<input>