【译】React中受控的和非受控的表单输入没必要复杂化

这是一本书的一个章节,有关 react form 中的受控组件和非受控组件,感谢做者。html

原文连接:goshakkk.name/controlled-…前端

你可能已经看过不少文章说“你不该该使用 setState ”,而文档中声称“ refs 是很差的”……这是很矛盾的。很难理解如何“作到正确”,作选择的标准是什么。

到底应该怎样建立 form 呢?node

毕竟,form 是不少 web 应用程序的核心,而在 React 中处理 form 彷佛有一点基础。react

不要怕,让我来想你展现这些方法的不一样,以及你应该选择哪种。web

非受控的

非受控输入框就像传统的 HTML 输入框同样:redux

class Form extends Component {
  render() {
    return (
      <div> <input type="text" /> </div> ); } } 复制代码

它们记录了你输入的信息,你可使用 ref 获取它们的值。例如,在按钮的 onClick 处理中:canvas

class Form extends Component {
  handleSubmitClick = () => {
    const name = this._name.value;
    // do something with `name`
  }

  render() {
    return (
      <div> <input type="text" ref={input => this._name = input} /> <button onClick={this.handleSubmitClick}>Sign up</button> </div> ); } } 复制代码

换句话说,当你须要的时候你须要从表单域中“拉”表单值。当表单提交时这种状况会发生。微信

这是最简单的实现表单输入的方式,确定会有这样使用的有效案例:在现实中处理简单的表单,还有学习 react 的时候。前端工程师

然而他不够强大,因此咱们看一下接下来这些受控的输入框。dom

受控的

一个受控输入框接收它的当前值做为一个属性,而且有一个回调来修改它的值。你能够说这是处理这件事的一种更“ React 的方式”(不表明你老是要使用这种方式)。

<input value={someValue} onChange={handleChange} />
复制代码

这是很好的……可是这个输入框的值必需要存在于某处的state中。一般,渲染输入框的组件(即表单组件)把它保存在它的state中:

class Form extends Component {
  constructor() {
    super();
    this.state = {
      name: '',
    };
  }

  handleNameChange = (event) => {
    this.setState({ name: event.target.value });
  };

  render() {
    return (
      <div> <input type="text" value={this.state.name} onChange={this.handleNameChange} /> </div> ); } } 复制代码

(固然,它能够保存在另外一个组件的状态中,甚至是独立的状态存储,例如 Redux

每次你输入一个新的字符,handleNameChange 被调用,他接收输入的新值并把它设置到 state 中。

  • 开始是一个空字符串——''
  • 输入一个a而且handleNameChange获取了一个a并调用setState。输入框接着从新渲染为拥有一个 value 为a
  • 输入bhandleNameChange获取到值ab并设置到 state 中,输入框再次从新渲染,如今带有属性value="ab"

这种流程把值的变化“推”给表单组件,所以Form组件始终拥有输入框的当前值,不须要明确地去要值。

这意味着你的数据( state )和 UI(输入框)老是同步的,state 提供值给输入框,输入框请求Form修改当前值。

这也意味着表单组件可以马上响应输入框变化,例如:

可是若是你不须要这些而且认为非受控的会更简单,那就去吧。

什么使一个元素“受控”

固然,有其余的表单元素:复选框、单选框、下拉框、文本域。

若是经过一个 prop 来设置一个表单元素的 value ,它变为“受控的”,就这样。

每个表单元素有不一样的用来设置 value 的 prop ,下面是一个总结的小表格

Element Value property Change callback New value in the callback
<input type="text" /> value="string" onChange event.target.value
<input type="checkbox" /> checked={boolean} onChange event.target.checked
<input type="radio" /> checked={boolean} onChange event.target.checked
<textarea /> value="string" onChange event.target.value
<select /> value="option value" onChange event.target.value

结论

受控和非受控表单字段都有它们的价值,评估具体的场景来选择方法——对你有用的就足够了。

若是你的表单在 UI 反馈方面特别简单,非受控的使用 refs 彻底能够,你没必要听各类文章说“很差”。

特性 非受控的 受控的
一次性取值(如:提交时) true true
提交时校验 true true
实时表单域校验 false true
按条件禁用提交按钮 false true
强制输入格式 false true
多输入框控制单个数据 false true
动态输入框 false true

并且,这不是一种一劳永逸的决定:你老是能够迁移到受控输入框。从非受控输入迁移到受控输入并不困难

最后,这是个人有关React中表单的文章的组织清单

参考文献


关于译者:第一次翻译文章,英语水平不好,表述不够优雅,有问题欢迎指正。

本文首发于掘金社区,转载请知悉本人,防止窃取附上我的小站,后续文章会同步。


最后发一条小广告,字节跳动招各类级别前端工程师,从 HTML五、 CSS三、Typescript、React、canvas、node 到 WebRTC、WebAssembly、WebGL,以及C++、Electron 等等,各类有趣的事情。联系微信 / QQ 1091381572 备注掘金,发简历给我,欢迎投递。

相关文章
相关标签/搜索