在React中受控和非受控的表单输入并不需要太复杂

原文:(https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/)

你也许在很多文章中看到过说“you shouldn’t use setState…”或者声称“refs are bad”…这是很矛盾的事。这让我们很难理解怎么才能正确取值甚至说选择的标准到底是什么。
你会认为到底应该怎么操作表单?
毕竟,表单事很多web应用程序的核心。并且,react中操作表单似乎是一种基础操作?
不要担心,让我告诉你这些方法之间的差异,以及应该如何使用。

非受控组件

非受控组件的输入框类似于传统的表单输入

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

它能够记住你输入了什么,你可以使用一个ref来获取它的值。例如,一个按钮的onClick操作:

class Form extends Component {
  handleSubmitClick = () => {
    const name = this._name.value;
  }
  render() {
    return  (
      <div>
        <input type="text" ref={input => this._name = input} />
        <button onClick={this.handleSubmitClick}>Sign up</button>
      </div>
    );
  }
}

不同的是,当你需要的时候,你就必须从这个区域里“拉取”值。通常发生在表单提交的时候。

这是实现表单输入的最简单的方式。在现实世界中学习使用react操作简单的表单时,这无疑是一个很有效的使用方法。

不过,它没有那么强大,让我们接下来看看受控组建的输入表单。

受控组件

一个受控组件接受当前的值作为参数,并且在值发生改变的时候执行回调函数。你可以说这是一种更接近的“react 方法”(这并不意味着你应该一直使用它)。

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

这样没有问题,但是input的值必须是存在的state。通常来说,渲染成input框的组件(即表单组件)就保存在它的state中:
(当然,那也可以是另一个组件的state,甚至独立存在于状态储存中,比如说redux。)

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

每次你键入了一个新的字符,就会调用handleNameChange。它会获取input最新的值并在state中设置。
这里写图片描述

  • 开始设置值为空字符串—''
  • 你输入一个a,然后执行handleNameChange获得a并且设置了setState,然后input输入框a被重新渲染
  • 你继续键入bhandleNameChange获得ab并且设置state,input输入框再次被重新渲染,现在的值是value=ab
     
    这种“推入式”的流程改变了表单控件,因此表单控件总是能够一直获取输入框当前的值,而不用明确知道对象是谁。

这意味着你的数据state以及UIinput总是异步的。状态将值赋給输入框,输入框通知表单改变当前的值。

这也意味着输入框发生变化时表单组件能够及时响应;例如:
- 就地反馈,例如验证
- 禁用按钮,除非所有字段都是有效数据
- 执行特定的输入格式,例如信用卡号码

但是如果你并不需要这些,认为不受控组件更简单一点,那就用不受控组件吧。

什么使元素“受控”

当然,还有其他的表单元素。你可以使用checkboxesradios以及selectstextareas
如果你通过参数来设置表单元素的值,就可以让它成为“受控组件”,就这么简单。
不过,每个表单元素都有一个不同的支持来设置该值,所以这里有一个小表来总结:

ElementValue propertyChange callbackNew value in the callback
<input type="text" />value="string"onChangeevent.target.value
<input type="checkbox" />value={boolean}onChangeevent.target.checked
<input type="radio" />value={boolean}onChangeevent.target.checked
<textarea/>value="string"onChangeevent.target.value
<select/>value="option value"onChangeevent.target.value

结论

受控和不受控表单字段都有它们的优点。评估你的具体情况并选择最合适的—对你最有效的方法就足够了。

如果你的表单在UI反馈方面极其简单,不受控的参考时完全合适的。你不需要听从许多文章说这是不好的。

featureuncontrolledcontrolled
一次性检索提交(例如submit
字段即时验证
有条件的禁用提交按钮
强制输入的格式
一段数据分多个输入框
动态输入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值