《React官方文档》之Forms

原文链接  译者:黄文海

表单(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

(0)
上一篇 2021年8月28日
下一篇 2021年8月28日

相关推荐

发表回复

登录后才能评论