受控组件与非受控组件在React中没那么复杂[自译]

原文链接:https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
受控组件与非受控组件

You may have seen many articles saying “you shouldn’t use setState,”
and the docs are claiming “refs are bad”… That is so contradictory.
It’s hard to understand how to “get it right” and even what are the
criteria for choosing.

你可能已经看过很多文章说到关于“你不应该使用 setState”并且这些文章还陈述到“refs属性不好”云云。但正相反。要理解怎么正确使用甚至是明白用怎样的准则去选择它们是非常难得。

How the hell are you supposed to make forms?

那么,你究竟改如何来构造表单呢?

After all, forms are central to many web apps out there. And yet, form
handling in React seems to be a bit of a… corner stone?

毕竟,对于多数的web app来说表单是核心部分。然而,在React中表单的构造看上去有一点…基础?

Fear no more. Let me show you the differences between the approaches,
as well as when you should use each.

别怕,让我来告诉你这之中的区别,当你都需要使用它们时。

非受控

Uncontrolled inputs are like traditional HTML form inputs:

非受控表单输入更像是传统的HTML表单输入:

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

They remember what you typed. You can then get their value using a ref. For example, in onClick handler of a button:

它们会记下你所敲击的内容。你能通过使用ref的方式来获得到它们的value。例如,下列代码在button上的onClick handler

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

In other words, you have to ‘pull’ the value from the field when you need it. This can happen when the form is submitted.

That is the simplest way to implement the form inputs. There certainly
are valid cases for using it: in simple forms in the real world; and
when learning React.

换句话说,当你提交表单需要这些值的时候不得不从字段中去获取它们。这是实现表单输入最简单的方法。肯定有合理的场景会使用到这样的表单。

It’s not as powerful, though, so let’s see those controlled inputs next.

但是好像并没有那么有力,接下来让我们来看看那些受控的输入。

受控

A controlled input accepts its current value as a prop, as well as a callback to change that value. You could say it’s a more “React way” of approaching this (which doesn’t mean you should always use it).

一个受控的输入会以prop的方式接受它当前的value,同时也会有一个callback去改变这个value。你可以说这是一种更加“React“的方式(但也不意味着你必须使用这种方式)

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

Which is fine and all… but the value of this input has to live in the state somewhere. Typically, the component that renders the input (aka the form component) saves that in its state:

那个更好呢…但是input(表单)的值应当存储在某个地方。通常,渲染表单的组件会存储在它的states里:

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

(Of course, it can be in the state of another component, or even in the separate state store, like Redux.)

当然,它能够存储在另一个组件的state里,甚至是存放在分离的state store中,例如Redux

Every time you type a new character, handleNameChange is called. It takes in the new value of the input and sets it in the state.

每当你打下一个新字符,handleNameChange就会被唤醒。它会成为input的新的value值同时也会被存储在state当中;
这里写图片描述

It starts out as an empty string — ““.

它从一个空字符串开始

You type a and handleNameChange gets an a and calls setState. The
input is then re-rendered to have the value of a.

你输入一个 “a” 然后handleNameChange就获取到一个 “a” 并且使用了setState方法,再然后input输入框就进行了重新渲染并得到”a”的值

You type b. handleNameChange gets the value of ab and sets that to the
state. The input is re-rendered once more, now with value=”ab”.

你输入一个”b”,同样的步骤会像输入”a”时一样进行

这样一个表单组件推进value改变的方式,使得表单组件总是能够实时的得到input的真实值,不需要在需要的时候明确的去要求得到这样一个值。

这意味着你的数据(state)和你的UI总是同步的。数据告诉input value值,input告诉表单去改变现在的value值,同时也意味着表单组件对于input的改变是响应式的,例如

  • 时时的反馈,进行校验
  • 当表单数据存在无效时禁用按钮
  • 对类似于信用卡号、身份证号的输入框进行特殊的时时校验
    但是,如果你不会使用到这些场景非受控组件会更加简单,那就用吧

什么使得一个元素”受控”

[译者注:省略了一些无关紧要的话未翻]

ElementValue 属性回调函数New value in the callback
<input type="text" />value=”string”onChangeevent.target.value
<input type="checkbox" />checked={boolean}onChangeevent.target.checked
<input type="radio" />checked={boolean}onChangeevent.target.checked
<textarea />value=”string”onChangeevent.target.value
<select />value=”option value”onChangeevent.target.value

总结

受控与非受控组件有各自的有点,评估你的特定的场景选择适合于你的那个方法。如果你的表单在UI反馈机制上非常简单,那么非受控的带有refs的组件就足够了。

[译者注:省略了一些无关紧要的话未翻]

译者注:官方并不推荐过分使用ref,凡事需要时时进行交互的表单组件就应该是受控的,例如需要各种时时校验、disable按钮、输入间有组合关系等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值