鍍金池/ 教程/ HTML/ 表單
React 組件
Redux 的基礎(chǔ)概念
JSX
DOM 操作
在 React 應(yīng)用中使用 Redux
進(jìn)化 Flux
Webpack 配置 React 開發(fā)環(huán)境
服務(wù)器端渲染
組合組件
表單
屬性擴(kuò)散
開發(fā)環(huán)境配置
組件生命周期
Data Flow
JSX 與 HTML 的差異
組件間通信
使用 JSX
事件處理
Flux
React 概覽
Mixins
Redux

表單

表單不同于其他 HTML 元素,因?yàn)樗憫?yīng)用戶的交互,顯示不同的狀態(tài),所以在 React 里面會(huì)有點(diǎn)特殊。

狀態(tài)屬性

表單元素有這么幾種屬于狀態(tài)的屬性:

  • value,對(duì)應(yīng) <input><textarea> 所有
  • checked,對(duì)應(yīng)類型為 checkboxradio<input> 所有
  • selected,對(duì)應(yīng) <option> 所有

在 HTML 中 <textarea> 的值可以由子節(jié)點(diǎn)(文本)賦值,但是在 React 中,要用 value 來設(shè)置。

表單元素包含以上任意一種狀態(tài)屬性都支持 onChange 事件監(jiān)聽狀態(tài)值的更改。

針對(duì)這些狀態(tài)屬性不同的處理策略,表單元素在 React 里面有兩種表現(xiàn)形式。

受控組件

對(duì)于設(shè)置了上面提到的對(duì)應(yīng)“狀態(tài)屬性“值的表單元素就是受控表單組件,比如:

render: function() {
    return <input type="text" value="hello"/>;
}

一個(gè)受控的表單組件,它所有狀態(tài)屬性更改涉及 UI 的變更都由 React 來控制(狀態(tài)屬性綁定 UI)。比如上面代碼里的 <input> 輸入框,用戶輸入內(nèi)容,用戶輸入的內(nèi)容不會(huì)顯示(輸入框總是顯示狀態(tài)屬性 value 的值 hello),這有點(diǎn)顛覆我們的認(rèn)知了,所以說這是受控組件,不是原來默認(rèn)的表單元素了。

如果你希望輸入的內(nèi)容反饋到輸入框,就要用 onChange 事件改變狀態(tài)屬性 value 的值:

getInitialState: function() {
    return {value: 'hello'};
},
handleChange: function(event) {
    this.setState({value: event.target.value});
},
render: function() {
    var value = this.state.value;
    return <input type="text" value={value} onChange={this.handleChange} />;
}

使用這種模式非常容易實(shí)現(xiàn)類似對(duì)用戶輸入的驗(yàn)證,或者對(duì)用戶交互做額外的處理,比如截?cái)嘧疃噍斎?40個(gè)字符:

handleChange: function(event) {
    this.setState({value: event.target.value.substr(0, 140)});
}

非受控組件

和受控組件相對(duì),如果表單元素沒有設(shè)置自己的“狀態(tài)屬性”,或者屬性值設(shè)置為 null,這時(shí)候就是非受控組件。

它的表現(xiàn)就符合普通的表單元素,正常響應(yīng)用戶的操作。

同樣,你也可以綁定 onChange 事件處理交互。

如果你想要給“狀態(tài)屬性”設(shè)置默認(rèn)值,就要用 React 提供的特殊屬性 defaultValue,對(duì)于 checked 會(huì)有 defaultChecked<option> 也是使用 defaultValue。

為什么要有受控組件?

引入受控組件不是說它有什么好處,而是因?yàn)?React 的 UI 渲染機(jī)制,對(duì)于表單元素不得不引入這一特殊的處理方式。

在瀏覽器 DOM 里面是有區(qū)分 attributeproperty 的。attribute 是在 HTML 里指定的屬性,而每個(gè) HTML 元素在 JS 對(duì)應(yīng)是一個(gè) DOM 節(jié)點(diǎn)對(duì)象,這個(gè)對(duì)象擁有的屬性就是 property(可以在 console 里展開一個(gè) DOM 節(jié)點(diǎn)對(duì)象看一下,HTML attributes 只是對(duì)應(yīng)其中的一部分屬性),attribute 對(duì)應(yīng)的 property 會(huì)從 attribute 拿到初始值,有些會(huì)有相同的名稱,但是有些名稱會(huì)不一樣,比如 attribute class 對(duì)應(yīng)的 property 就是 className。(詳細(xì)解釋:.prop,.prop() vs .attr()

回到 React 里的 <input> 輸入框,當(dāng)用戶輸入內(nèi)容的時(shí)候,輸入框的 value property 會(huì)改變,但是 value attribute 依然會(huì)是 HTML 上指定的值(attribute 要用 setAttribute 去更改)。

React 組件必須呈現(xiàn)這個(gè)組件的狀態(tài)視圖,這個(gè)視圖 HTML 是由 render 生成,所以對(duì)于

render: function() {
    return <input type="text" value="hello"/>;
}

在任意時(shí)刻,這個(gè)視圖總是返回一個(gè)顯示 hello 的輸入框。

<select>

在 HTML 中 <select> 標(biāo)簽指定選中項(xiàng)都是通過對(duì)應(yīng) <option>selected 屬性來做的,但是在 React 修改成統(tǒng)一使用 value。

所以沒有一個(gè) selected 的狀態(tài)屬性。

<select value="B">
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
</select>

你可以通過傳遞一個(gè)數(shù)組指定多個(gè)選中項(xiàng):<select multiple={true} value={['B', 'C']}>

上一篇:JSX下一篇:DOM 操作