原文

In most cases, we recommend using controlled components to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.

大多数情况下,我们建议使用受控组件来实现表单,数据可以直接被React组件处理。如果需要使用DOM本身处理表单数据,可以使用非受控组件。

To write an uncontrolled component, instead of writing an event handler for every state update, you can use a ref to get form values from the DOM.

在非受控组件中,不用在为每一个状态更新设置事件处理器,直接使用引用从DOM中获取表单值即可。

For example, this code accepts a single name in an uncontrolled component:

如下所示,在非受控组件中获取一个简单的Name表单值:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={(input) => this.input = input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

Try it on CodePen.

打开CodePen试一试

Since an uncontrolled component keeps the source of truth in the DOM, it is sometimes easier to integrate React and non-React code when using uncontrolled components. It can also be slightly less code if you want to be quick and dirty. Otherwise, you should usually use controlled components.

由于非受控组件直接操作DOM,非React代码可以非常简单的和React代码集成在一起。同时这样编码比较少,比较快,但有点不干净。当然,大多数情况下还是需要使用受控组件。

If it’s still not clear which type of component you should use for a particular situation, you might find this article on controlled versus uncontrolled inputs to be helpful.

如果你对如何选择受控组件和非受控组件存在疑惑,可以参考这篇对比受控组件和非受控组件中输入问题的文章获取帮助。

默认值(Default Values)

In the React rendering lifecycle, the value attribute on form elements will override the value in the DOM. With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value.

在React渲染生命周期中,表单元素的value属性会被重写。在非受控组件中,只需要使用React设置默认值,不能控制随后的表单更新操作。为了解决这个问题,使用特殊的defautlValue代替value即可。

render() {
  return (
    <form onSubmit={this.handleSubmit}>
      <label>
        Name:
        <input
          defaultValue="Bob"
          type="text"
          ref={(input) => this.input = input} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

Likewise, <input type="checkbox"> and <input type="radio"> support defaultChecked, and <select> and <textarea> supports defaultValue.

另外,在<input type="checkbox"><input type="radio">元素使用defaultChecked<select><textarea>同样使用defaultValue