原文链接 译者:黄文海
表单(Forms)
诸如<input>、
<textarea>和
<option>的
表单组件与其它原生(native)组件不同,因为它们可以通过用户交互而被改变。
这些组件提供的接口使得管理表单对用户交互的响应更加容易。
有关<form>事件的信息见Form Events。
交互属性(Interactive Props)
表单组件支持一些受用户交互影响的属性(props):
value,
<input>
和<textarea>
组件支持该属性。checked
,类型为checkbox或者
radio的
<input>组件支持该属性。
selected
,<option>组件支持该属性。
在HTML中,<textarea>的值是通过其子节点设置的。在React中,你应该使用value替代。
通过为onChange属性设置一个回调函数,表单组件允许侦听改变(Change)事件。onChange属性以跨浏览器的方式来触发对用户交互的响应,包括:
<input>
或者<textarea>的值发生变化。
<input>的checked状态发生变化。
<option>的
selected状态发生变化
。
和所有的DOM事件一样,onChange属性受所有的原生组件支持,并可用于侦听冒泡改变事件(bubbled change events)。
注意:对于
<input>和
<textarea>,
onChange优先于并且通常应该代替DOM的内置
oninput
事件处理器。
受控组件(Controlled Components)
一个设置了值的<input>组件是一个受控组件。在一个受控的<input>里,渲染后的元素的值总是反映该组件的value属性。比如:
render: function() {
return <input type="text" value="Hello!" />;
}
这段代码将渲染为一个值总是为“Hello!”的输入框。任何用户输入都不会对该渲染后的元素其作用,因为React已将其值声明为“Hello!”。如果你想响应用户输入来更新该组件的值,你可以使用onChange事件:
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}
在这个例子中,我们简单地接受用户提供的最新值并据此更新<input>组件的value属性。这种模式使得实现能够响应或者校验用户交互的界面变得容易。比如:
handleChange: function(event) {
this.setState({value: event.target.value.substr(0, 140)});
}
这段代码能够接受用户输入,但是它只截取输入值的前140个字符。
复选框和单选按钮的潜在问题
注意一下,为了使对复选框和单选按钮的change事件处理统一化,React用click事件代替了
change
事件。大多数情况下,其表现符合我们的预期,除了在change事件处理器中调用preventDefault这种情形之外。preventDefault
即使是在
checked属性被切换的情况下也会
阻止浏览器改变输入组件的外观。这种情形的一个变通方案是移除对preventDefault的调用或者将对checked属性的切换放在setTimeout中执行。
未受控组件(Uncontrolled Components)
一个未提供value属性(或者该属性值为null)的<input>组件是一个未受控组件。在一个未受控的<input>里,渲染后的元素的值将反映用户的输入。比如:
render: function() {
return <input type="text" />;
}
这段代码渲染成一个初始值为空的输入框。任何用户输入会直接反映在这个渲染后的元素上。如果你需要侦听对该元素值的更新,和你使用受控组件一样,你可以使用onChange事件。
默认值(Default Value)
如果你想初始化一个带非空值的组件,你可以提供一个defaultValue属性。比如:
render: function() {
return <input type="text" defaultValue="Hello!" />;
}
这个例子运行起来很像上面的未受控组件的例子。
同样地,<input>支持defaultChecked属性,<select>支持defaultValue属性。
注意:
defaultValue属性和
defaultChecked属性仅在初次渲染时使用。如果你需要在后续的渲染中更新这些值,你需要使用受控组件。
高级主题
为什么有受控组件?
在React中使用如<input>之类的
表单组件会带来一个使用传统HTML表单所未面临的挑战。比如,在HTML中:
<input type="text" name="title" value="Untitled" />
这段代码会渲染一个初始化时值为“Untitled”的输入框。当用户更新该输入框时,该节点的value属性(property)将会变化。然而,node.getAttribute(‘value’)将仍然返回初始化时的值,即“Untitled”。
不像HTML,React组件必须在任何时间点呈现视图的状态而不仅仅是在初始化的时候。比如,在React中:
render: function() {
return <input type="text" name="title" value="Untitled" />;
}
由于这个方法描述了任何时间点的视图,文本输入框的值应该总是“Untitled”。
为什么使用文本域的值?
在HTML中,<textarea>的值通常是由其子节点设置的:
<!-- 反模式:别这样做! -->
<textarea name="description">This is the description.</textarea>
对于HTML,这样做便于允许开发人员提供多行值。然而,由于React是JavaScript,我们没有字符串限制,并且如果我们需要换行的话可以使用“/n”。在一个有value和defaultValue的环境中,<textarea>的子节点所扮演的角色是有歧义的。有鉴于此,你设置<textarea>值的时候不应使用子节点:
<textarea name="description" value="This is a description." />
如果你非要使用子节点,那么它们将表现地像defaultValue。
为什么使用下拉列表的值?
HTML中的<select>组件中选中的<option>通常是通过相应选项的
selected属性(attributue)指定的。在React中,为了使组件更加易于操纵,下列格式作为替代被采用:
<select value="B">
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
如果要创建的是未受控组件,那么用defaultValue来替代。
注意:
你可以给value属性(attribute)传入一个数组,这样允许你在一个
select
标签中选中多个选项:<select multiple={true} value={['B', 'C']}>。
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/117594.html