React中的受控组件和非受控组件不必太复杂

哈Ha!我向您介绍了Gosha Arinich撰写的文章“ React中的受控和不受控制的表单输入不必复杂”的翻译。

您可能已经看到很多文章说“您不应该使用setState”,而文档声称“ refs不好。”这都是非常矛盾的。有时候,很难弄清楚如何正确处理,那么在这些方法之间进行选择的标准是什么

?那么,如何制作表单呢?毕竟,表单是许多Web应用程序的核心,

但是,React中的表单处理才是基石,不是吗?太难了,让我向您展示这些方法之间的差异以及何时使用每种方法。

非托管组件


非托管组件就像常规的HTML形式:

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

他们会记住您键入的所有内容。然后,您可以使用ref获得它们的值。例如,在onClick处理程序中:


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研究中还是最简单的形式。
但是,此方法不太灵活,因此让我们更好地看一下托管组件。

托管组件:


托管组件将其当前值作为prop接受,并接受更改此值的回调。您可以说这是控制组件的“更主动”方式,但这并不意味着您应该始终使用此方法。

<input value={someValue} onChange={handleChange} />

这一切都很好,但是输入表单的值必须处于某种状态。通常,呈现输入表单(即表单)的组件会将其保存为状态:


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。它采用输入表单的新值并将其写入状态。

图片

  • 全部以空行开头-'';
  • 您输入字母“ a”,handleNameChange将其获取并调用setState。然后,再次使用值“ a”呈现输入表单;
  • 您输入字母“ b”,handleNameChange获得值“ ab”并将其设置为state。Opet输入表单已呈现,但现在值为'ab'。

该流似乎将更改“推送”到表单中,这就是为什么组件始终具有输入数据的当前值而无需显式更新请求的原因。

这意味着您的数据(状态)和用户界面(输入表单)始终保持同步。状态为表单赋值,而表单则更改当前状态值。

这也意味着表单可以立即对更改做出响应,而这又对于以下操作是必需的:

  • 快速反馈,例如验证;
  • 禁用特定按钮,直到所有表单字段均有效;
  • 允许处理某些输入字段格式,例如信用卡号。

但是,如果您不需要它,并且认为非托管组件要简单得多,请使用它们。

是什么使组件“可管理”?


当然,还有其他表单元素,例如:复选框,单选,textarea和select。
在使用组件设置其值时,该组件将变得可管理。就这样。

但是,每个表单元素都有不同的设置值的方式,因此,这里是一个小表格,供您一般理解:

元件回调以进行更改回调中的新值
<input type="text" />
值=“字符串”onChangeevent.target.value
<input type="checkbox" />
已检查= {boolean}onChangeevent.target.checked
<input type="radio" />
已检查= {boolean}onChangeevent.target.checked
<textarea />
值=“字符串”onChangeevent.target.value
<select />
值=“选项值”onChangeevent.target.value

发现


托管和非托管组件都有优点和缺点。评估特定情况并选择一种方法-如果这对您有用,那么为什么不利用它呢?

如果您的表单与用户界面的交互非常简单,那么非托管组件非常适合您。您不必听各种文章说的不好。

图片

此外,选择组件类型并不是一劳永逸的决定:您始终可以将非托管组件替换为托管组件。从一个过渡到另一个并不是那么困难。

All Articles