HTML 表單用於蒐集不一樣類型的用戶輸入。瀏覽器
<form> 元素定義 HTML 表單:函數
<form> . form elements . </form>
表單元素指的是不一樣類型的 input 元素、複選框、單選按鈕、提交按鈕等等。
當用戶提交表單時瀏覽器會打開一個新頁面,若是你但願 React 中保持這個行爲,也能夠工做。可是多數狀況下,用一個處理表單提交併訪問用戶輸入到表單中的數據的 JavaScript 函數也很方便。實現這一點的標準方法是使用一種稱爲「受控組件(controlled components)」的技術。this
在 HTML 中,表單元素如 <input>,<textarea> 和 <select> 表單元素一般保持本身的狀態,並根據用戶輸入進行更新。而在 React 中,可變狀態通常保存在組件的 state(狀態) 屬性中,而且只能經過 setState() 更新。code
咱們能夠經過使 React 的 state 成爲 「單一數據源原則」 來結合這兩個形式。而後渲染表單的 React 組件也能夠控制在用戶輸入以後的行爲。這種形式,其值由 React 控制的輸入表單元素稱爲「受控組件」。component
一個常規的受控組件的形式例子:orm
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: /*① 設置表單元素的value屬性以後,其顯示值將由this.state.value決定,以知足React狀態的同一數據理念。*/ /*② 每次鍵盤敲擊以後會執行handleChange方法以更新React狀態,顯示值也將隨着用戶的輸入改變。*/ <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } }
因爲 value 屬性設置在咱們的表單元素上,顯示的值老是 this.state.value,以知足 state 狀態的同一數據理念。因爲 handleChange 在每次敲擊鍵盤時運行,以更新 React state(狀態),顯示的值將更新爲用戶的輸入。事件
對於受控組件來講,每一次 state(狀態) 變化都會伴有相關聯的處理函數。這使得能夠直接修改或驗證用戶的輸入。好比,若是咱們但願強制 name 的輸入都是大寫字母,能夠這樣來寫 handleChange 方法:ip
handleChange(event) { this.setState({value: event.target.value.toUpperCase()}); }
上面例子中是以input爲例來寫的,其實其餘的表單元素基本形式是差很少的。element
<textarea value={this.state.value} onChange={this.handleChange} />
<select value={this.state.value} onChange={this.handleChange}> …… </select>
當您須要處理多個受控的 表單元素時,您能夠爲每一個元素添加一個 name 屬性,而且讓處理函數根據 event.target.name 的值來選擇要作什麼。開發
因爲 setState() 自動將部分狀態合併到當前狀態,因此咱們只須要調用更改的部分便可。
有時使用受控組件有些乏味,由於你須要爲每個可更改的數據提供事件處理器,並經過 React 組件管理全部輸入狀態。當你將已經存在的代碼轉換爲 React 時,或將 React 應用程序與非 React 庫集成時,這可能變得特別煩人。在這些狀況下,您可能須要使用不受控的組件,用於實現輸入表單的替代技術。
在大多數狀況下,咱們推薦使用受控組件來實現表單。在受控組件中,表單數據由 React 組件負責處理。另一個選擇是不受控組件,其表單數據由 DOM 元素自己處理。
要編寫一個未控制組件,你可使用一個 ref 來從 DOM 得到 表單值,而不是爲每一個狀態更新編寫一個事件處理程序。
例如,在不受控組件中,如下代碼接受一個單獨的名字 :
class NameForm extends React.Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(event) { alert('A name was submitted: ' + this.input.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={(input) => this.input = input} /> </label> <input type="submit" value="Submit" /> </form> ); } }
由於不受控組件的數據來源是 DOM 元素,當使用不受控組件時很容易實現 React 代碼與非 React 代碼的集成。若是你但願的是快速開發、不要求代碼質量,不受控組件能夠必定程度上減小代碼量。不然。你應該使用受控組件。