【React系列】受控组件(Controlled Components)和不受控组件

受控组件

表单

HTML 表单用于搜集不一样类型的用户输入。浏览器

<form> 元素

<form> 元素定义 HTML 表单:函数

<form>
 .
form elements
 .
</form>

表单元素

表单元素指的是不一样类型的 input 元素、复选框、单选按钮、提交按钮等等。
当用户提交表单时浏览器会打开一个新页面,若是你但愿 React 中保持这个行为,也能够工做。可是多数状况下,用一个处理表单提交并访问用户输入到表单中的数据的 JavaScript 函数也很方便。实现这一点的标准方法是使用一种称为“受控组件(controlled components)”的技术。this

受控组件(Controlled Components)

在 HTML 中,表单元素如 <input>,<textarea> 和 <select> 表单元素一般保持本身的状态,并根据用户输入进行更新。而在 React 中,可变状态通常保存在组件的 state(状态) 属性中,而且只能经过 setState() 更新。code

咱们能够经过使 React 的 state 成为 “单一数据源原则” 来结合这两个形式。而后渲染表单的 React 组件也能够控制在用户输入以后的行为。这种形式,其值由 React 控制的输入表单元素称为“受控组件”。component

一个常规的受控组件的形式例子:orm

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

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

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          /*① 设置表单元素的value属性以后,其显示值将由this.state.value决定,以知足React状态的同一数据理念。*/
          /*② 每次键盘敲击以后会执行handleChange方法以更新React状态,显示值也将随着用户的输入改变。*/
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

因为 value 属性设置在咱们的表单元素上,显示的值老是 this.state.value,以知足 state 状态的同一数据理念。因为 handleChange 在每次敲击键盘时运行,以更新 React state(状态),显示的值将更新为用户的输入。事件

对于受控组件来讲,每一次 state(状态) 变化都会伴有相关联的处理函数。这使得能够直接修改或验证用户的输入。好比,若是咱们但愿强制 name 的输入都是大写字母,能够这样来写 handleChange 方法:ip

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});
}

受控表单的表单元素

上面例子中是以input为例来写的,其实其余的表单元素基本形式是差很少的。element

textare

<textarea value={this.state.value} onChange={this.handleChange} />

select

<select value={this.state.value} onChange={this.handleChange}>
……
</select>

处理多个输入元素

当您须要处理多个受控的 表单元素时,您能够为每一个元素添加一个 name 属性,而且让处理函数根据 event.target.name 的值来选择要作什么。开发

因为 setState() 自动将部分状态合并到当前状态,因此咱们只须要调用更改的部分便可。

受控组件的替代方案

有时使用受控组件有些乏味,由于你须要为每个可更改的数据提供事件处理器,并经过 React 组件管理全部输入状态。当你将已经存在的代码转换为 React 时,或将 React 应用程序与非 React 库集成时,这可能变得特别烦人。在这些状况下,您可能须要使用不受控的组件,用于实现输入表单的替代技术。

不受控组件

在大多数状况下,咱们推荐使用受控组件来实现表单。在受控组件中,表单数据由 React 组件负责处理。另一个选择是不受控组件,其表单数据由 DOM 元素自己处理。

要编写一个未控制组件,你可使用一个 ref 来从 DOM 得到 表单值,而不是为每一个状态更新编写一个事件处理程序。

例如,在不受控组件中,如下代码接受一个单独的名字 :

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>
    );
  }
}

受控组件与不受控组件的选取

由于不受控组件的数据来源是 DOM 元素,当使用不受控组件时很容易实现 React 代码与非 React 代码的集成。若是你但愿的是快速开发、不要求代码质量,不受控组件能够必定程度上减小代码量。不然。你应该使用受控组件。

相关文章
相关标签/搜索