iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 20
1
Modern Web

I Want To Know React系列 第 20

I Want To Know React - 初探 Form & Controlled component

在這個章節中,我們將介紹在 React 中 form 與 input 相關 element 的使用方式。

然而為何需要把 form 這類的 element 特別拿出來講呢?

這是因為 HTML form element 跟其他一般 element(e.g. div span)有個不同處,使得 React 使用 form 的方式也會較為不同。

就讓我們先來看看 HTML form 到底有什麼特別處吧!

HTML Form 有自己的 state

常見的 HTML form 相關的 element 有以下幾種:

  • input
  • textarea
  • select

與其他一般大多數的 HTML element(e.g. div span)等不同,它們皆有一個特點:這些 HTML element 都可以接受使用者輸入資料。而使用者輸入的資料會存在 HTML form element 中,意思就是使用者輸入的資料就相當於這些 HTML form element 的 state。

換句話說,HTML form element 的特點在於它們天生就存有自己的 state。

HTML Form state vs. React state

由上可知,HTML form 擁有並管理自己的 state。

然而,React 本身也有管理 state 的功能。這時我們就面臨一個選擇:

  • 將 HTML form element 的 state 也交給 React 一併控管
  • 讓 HTML form element 管理自己的 state,React 不加以管控

以上兩種做法 React 都有支援。這兩種方式在 React 中分別有自己的名稱:

  • Controlled component(由 React 管控 HTML form element 的 state)
  • Uncontrolled component(由 HTML form element 自行管理 state)

Controlled component 與 Uncontrolled component 都有各自的使用情境。Uncontrolled component 將會在下一個章節介紹。以下會針對 Controlled component 介紹。

Controlled component

如果一個 form element 的 state(輸入值)是交由 React 控管的,我們就稱此 form element 為 controlled component。

當使用者在一個 controlled component 中輸入內容時,React 會抑制 component 的原生行為,並將輸入內容記錄在 state 中。

以下是一個 controlled component 的簡單範例:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

使用者也可以到 CodePen 中查看範例。

為何需要 controlled component

使用 controlled component 可以讓 React 一併管理 form element。

所有使用者的輸入行為都會藉由 event 被 "推送" 到 React state 中;React 在收到 event 後就可做出對應的 state 改動以將資料更新到 form element 上。

也就是說,form element 的內容永遠是由 state 同步的,React state 因此成為單一資料來源 (Single Source Of Truth)

如此會有幾個好處:

  • 所有 state 都是由 React 掌控,避免資料修改來源過多,導致維護難度提高
  • 所有資料改動的源頭都是在 React,因此開發者可以針對使用者的輸入都進行客製化的操作,例如設定初始值(initial value)、檢查是否被修改過(dirty)、格式驗證(validation)...etc,使得操作彈性提高
  • React 可以藉由 form 的 state 去連動修改其他 component 的資料,使得整個 UI/UX 可以更細緻

何時需要使用 controlled component

了解了好處之後,我們就可以推論出哪些狀況下需要使用 controlled component:

  • 需要對 form 檢查是否修改過(dirty)、格式驗證(validation)...etc 等狀況時
  • 需要取得 form 的 state 或內容去連動修改其他 component 時

簡單來講,當要取用 form 的輸入內容時,就應該使用 controlled component。

簡介 Controlled component 使用概念

使用 controlled component 其實有幾個重點:

  • 在 form element 中加上對應的 value prop,用來設定 form 的顯示內容
  • 在 form element 中加上 onChange event prop,用來接收使用者輸入的 event
  • 並在 callback 中,利用 event 取得使用者輸入的新值,並使用 setState 更新 value 的值

如此,form 的輸入 value 就會由 state 控制,而使用者輸入又會觸發對應的 setState 修改 value,進而更新 form 內容。

Controlled component 的實際操作語法將在下一章節中繼續介紹。

小結

在這個章節中我們學習到了 form 的特別之處:

  • HTML Form 有自己的 State

也了解在 React 中處理 form element 的兩種方式:

  • Controlled component:由 React 管控 HTML form element 的 state
  • Uncontrolled component:由 HTML form element 自行管理 state

最後還知道了 controlled component 的優點:

  • React 是 state 的 single source of truth
  • 可使操控性更高,例如可以設定初始值(initial value)、檢查是否被修改過(dirty)、格式驗證(validation)
  • 可以藉由 form 的 state 去連動修改其他 component 的資料,使得整個 UI/UX 可以更細緻

以及其使用情境:

  • 需要對 form 檢查是否修改過(dirty)、格式驗證(validation)...etc 等狀況時
  • 需要取得 form 的 state 或內容去連動修改其他 component 時

在下一章節中,我們將介紹 controlled component 的實際操作語法。

參考資料


上一篇
I Want To Know React - Key 的常見值 & 最佳實踐
下一篇
I Want To Know React - Controlled component 語法
系列文
I Want To Know React30

尚未有邦友留言

立即登入留言