表单组件,如:<input>、<textarea>、<option>等,这些组件不同于其他组件,它们可以通过用户交互发生变化。这些组件提供的响应用户交互的接口,使响应用户交互和管理表单数据更加容易。
1. 交互属性与事件
1.1 交互属性
表单组件会受到用户交互的影响而发生变化,表单组件与用户交互的属性有:
value:适用的组件类型有<input>(type="text")、<textarea>组件。checked:适用的组件类型有checkbox(type="checkbox")或radio(type="radio")类型的<input>组件。selected:适用于<option>组件。
1.2 事件
表单事件是控制表单组件及影响用户交互的重要方式。
表单组件可以通过 onChange 回调函数来监听组件变化。和所有 DOM 事件一样,所有的 HTML 原生组件都支持 onChange 属性,而且可以用来监听冒泡的 change 事件。
当用户做出以下交互时,我们可以使用onChange 监听交互并通过浏览器做出响应:
<input>或<textarea>的value发生变化时。<input>的checked状态改变时。<option>的selected状态改变时。
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} />;
}
});
React 支持所有HTML事件,这些事件在表单组件上同样适用。React 通过合成事件(SyntheticEvent)的实例处理事件,而SyntheticEvent是对浏览器事件的跨浏览器封装。
合成事件的实例会被传递到回调函数的参数中,我们可以通过syntheticEvent.target属性来访问触发事件的节点:
React.createClass({
getInitialState: function() {
return {value: 'niefengjun.cn'};
},
handleChange: function(syntheticEvent) {
// 通过 target访问触发事件的DOM节点
var DOMNode = syntheticEvent.target;
// 将用户输入值传入受控组件中
this.setState({value: DOMNode.value});
},
render: function() {
return <input type="text" value={this.state.value} onChange={this.handleChange} />;
}
});
1.3 name属性
对于Reac 来说,name属性并不是必须的。受控组件会把值存储到state中,并且表单的提交事件也会被拦截。而对于非受控组件来说,也可以通近refs来直接访问组件。但是name属性仍然是表组件中的一个重要属性:
- 对于传统的表单提交方式来说(
GET和POST提交),name属性是必须的。 - 浏览器会根据
name属性来自动填写 - 对于非约束组件来说,
name属性可以保证单选框只有一个可以被选中 - 使用第三方类库时,
name属性也有一定的作用
2. 文本框与下拉框:<textarea>、<select>
在HTML中,<textarea>元素通过子节点设置值,而<select>使用通常使用<option>设置选中状态。React 进行了规范,统一使用value属性进行设置。
对于<textarea>来说,在HTML中设置换行很简单,但在React 中需要使用\n实现换行。受控类型的<textarea>组件使用value属性设置值,非受控类型使用defaultValue属性设置。应当避免使用子节点设置组件值,使用子节点设置时相当于使用defaultValue设置:
<textarea name="description" value="这里是设置值的内容" />
对于<select>而言,使用value设置选中状态,可以使React 更方便的控制组件。非受控类型的<select>组件,同样使用defaultValue属性设置:
<select value="itbilu"> <option value="itbilu">niefengjun.cn</option> <option value="yijiebuyi">yijiebuyi.com</option> </select>
<select>组件支持多选,多选时需要设置multiple属性为true,并对value或defaultValue属性传递一个表示选中项的数组:
<select multiple={true} value={['itbilu', 'yijiebuyi']}>
<option value="itbilu">niefengjun.cn</option>
<option value="yijiebuyi">yijiebuyi.com</option>
</select>
当<select>组件设置为多选时,组件的value属性不会发生变化,只有选项<option>的selected属性会发生变化:
var MyForm = React.createClass({
getInitialState: function() {
return {options: ['itbilu']};
},
handleChange: function(syntheticEvent) {
var checked = [];
var slt = syntheticEvent.target;
for(let i=0; i<slt.length; i++){
var option = slt.options[i];
if(option.selected){
checked.push(option.value);
}
}
this.setState({options: checked});
},
render: function() {
return (<select multiple={true} value={this.state.options} onChange={this.handleChange}>
<option value="itbilu">niefengjun.cn</option>
<option value="yijiebuyi">yijiebuyi.com</option>
</select>)
}
});
3. 单选框与复选框:radio、checkbox
在HTML中,radio或checkbox类型的<input>与text类型的<input>行为完全一样。
而在React 中,单选框与复选框则使用了完全不同的控制方式。通常来说单选框与复选框的值是不变的,而变化的只有checked属性,所以只要控制单选框或复选框的checked属性即可。在非受控的单选框或复选框中,可以使用defaultChecked。
var MyForm = React.createClass({
getInitialState: function() {
return {checked: false};
},
handleChange: function(event) {
this.setState({checked: event.target.checked});
},
render: function() {
return (<input type="checkbox" checked={this.state.checked} onChange={this.handleChange} />)
}
});
