[譯]不要把React中的受控和非受控的form表單輸入搞復(fù)雜

原文地址:Controlled and uncontrolled form inputs in React don't have to be complicated
react的form受控和非受控話題

不要把React中的受控和非受控的form表單輸入搞復(fù)雜

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.

(譯:你可能已經(jīng)看過很多文章說:“你不應(yīng)該去使用 setState 去實現(xiàn)表單輸入(setState是受控)”,并且官方文檔聲稱:“使用 ref 的方式實現(xiàn)表單輸入是不好的(ref是非受控)”。這些是互相矛盾的。這是很難去理解的,怎么樣才能“得到正確的答案”,或者說選擇標準是什么?)

How the hell are you supposed to make forms? (翻譯:你到底應(yīng)該怎么去實現(xiàn)form表單?)

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?(翻譯:畢竟,表單是許多網(wǎng)絡(luò)應(yīng)用程序的核心。然而,React中的表單處理似乎有點像一個墻角石)

Fear no more. Let me show you the differences between the approaches, as well as when you should use each.(翻譯:不要擔心,讓我向你展示這些方法之間的差異,以及何時應(yīng)該使用哪一種方法。)

The Uncontrolled(非受控)

Uncontrolled inputs are like traditional HTML form inputs:(翻譯:非受控就像傳統(tǒng)的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:(翻譯:他們記得你輸入的內(nèi)容。然后,您可以使用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>
    );
  }
}

In other words, you have to ‘pull’ the value from the field when you need it. This can happen when the form is submitted.(翻譯:換句話說,當你需要使用它時,你必須在這個字段所在的form中拉取這個值,即this._name = input綁定,this._name.value拉取)

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.(翻譯:這是實現(xiàn)表單輸入的最簡單方法。也是在你學習react時,現(xiàn)實世界中,最簡單以及最有效的使用form表單的案例)

It’s not as powerful, though, so let’s see those controlled inputs next.(翻譯:然而,它沒有那么有效,讓我們接下來看看那些受控輸入)

The Controlled(受控)

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,以及改變該值的回調(diào)所組成。你可以說這是一種更接近“react思想”的方式。)

備注:但是這并不意味著你應(yīng)該總是使用它

<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值必須被存放在state中。通常,我們在使用表單組件時,是需要將其值保存在自身相關(guān)的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>
    );
  }
}

(Of course, it can be in the state of another component, or even in the separate state store, like Redux.)(翻譯:當然,它可以處于另一個組件的狀態(tài),甚至可以處于單獨的狀態(tài)存儲中,例如: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.(翻譯:每次鍵入新字符時,都會調(diào)用handleNameChange。這個方法將會把輸入的新值設(shè)置為相關(guān)的state狀態(tài)。)

image
  • It starts out as an empty string — ''.(翻譯:以空內(nèi)容開始)

  • 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并調(diào)用setState。然后重新呈現(xiàn)輸入的值“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時,handleNameChange獲取ab的值并將其設(shè)置為state。然后,輸入再次重新渲染,現(xiàn)在值是“ab”。)

This flow kind of ‘pushes’ the value changes to the form component, so the Form component always has the current value of the input, without needing to ask for it explicitly.(這種流將會把更改的值“推送”到表單組件,所以Form組件總是具有輸入的當前值,而不需要明確地要求它。)

This means your data (state) and UI (inputs) are always in sync. The state gives the value to the input, and the input asks the Form to change the current value.(翻譯:這意味著您的數(shù)據(jù)(狀態(tài))和UI(輸入)始終保持同步。狀態(tài)給輸入賦值,輸入通過Form的改變當前值。)

This also means that the form component can respond to input changes immediately; for example, by:(翻譯:這也意味著表單組件可以立即響應(yīng)輸入更改,例如可以實現(xiàn)如下內(nèi)容:)

  • in-place feedback, like validations(翻譯:就地反饋,如驗證)
  • disabling the button unless all fields have valid data(翻譯:除非所有字段都包含有效數(shù)據(jù),否則禁用該按鈕,應(yīng)用與提交驗證)
  • enforcing a specific input format, like credit card numbers(翻譯:強制執(zhí)行特定的輸入格式,如信用卡號)

But if you don’t need any of that and consider uncontrolled to be simpler, go for it.(翻譯:但是,如果你沒有這些需求,并考慮到非受控的簡單性,想要使用非受控,那也是可以的。)

What makes an element “controlled”(怎么使元素“受控”)

There are other form elements, of course. You have checkboxes and radios and selects and textareas.(翻譯:當然還有其他形式的元素:復(fù)選框、單選框、下拉框和文本域。)

A form element becomes “controlled” if you set its value via a prop. That’s all.(翻譯:如果通過prop設(shè)置其值,則表單元素將變?yōu)椤笆芸亍?。就這樣。)

Each of the form elements, though, has a different prop for setting that value, so here’s a little table to summarize:(翻譯:但是,每個表單元素都有不同的用于設(shè)置該值的prop,這里有一個小表可以總結(jié):)

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

Conclusion(結(jié)論)

Both the controlled and uncontrolled form fields have their merit. Evaluate your specific situation and pick the approach — what works for you is good enough.(翻譯:受控和不受控制的form字段都有其優(yōu)點。評估您的具體情況并選擇方法 - 有用即是足夠的。)

If your form is incredibly simple in terms of UI feedback, uncontrolled with refs is entirely fine. You don’t have to listen to what the various articles are saying is “bad.”(翻譯:如果您的表單在UI反饋方面非常簡單,那么非受控的參考完全沒問題。
你不必聽各種文章所說的“缺點”。)

feature uncontrolled controlled
one-time value retrieval (e.g. on submit) ? ?
validating on submit ? ?
instant field validation ? ?
conditionally disabling submit button ? ?
enforcing input format ? ?
several inputs for one piece of data ? ?
dynamic inputs ? ?

Also, this is not an once-and-for-all decision: you can always migrate to controlled inputs. Going from uncontrolled to controlled inputs is not hard.(翻譯:此外,這不是一勞永逸的決定:您始終可以遷移到受控輸入。從非受控form轉(zhuǎn)換到受控form并不難)

Finally, here’s the organized list of my posts about forms in React.(翻譯:最后,放上關(guān)于React中表單有組織的帖子列表

References(參考內(nèi)容)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,817評論 0 10
  • ——2012年12月美卡人物 生命的意義不僅限于生存 他拍戲出于偶然,在大一那年,機緣巧合認識了唐人公司投拍的電...
    hugh_diary閱讀 459評論 0 1
  • 天辰低著頭,把已經(jīng)熟睡的綿兒輕輕地放在地上。一絲微笑掛在他的嘴角,是那么溫暖,充滿了愛戀。淚水肆意地在他剛毅的面龐...
    路小札閱讀 1,040評論 0 3
  • 大雪是也閱讀 231評論 0 0

友情鏈接更多精彩內(nèi)容