【譯】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 備註掘金,發簡歷給我,歡迎投遞。

相關文章
相關標籤/搜索