@(React學習)javascript
諸如 <input>
、<textarea>
、<option>
這樣的表單組件不一樣於其餘組件,由於他們能夠經過用戶交互發生變化。這些組件提供的界面使響應用戶交互的表單數據處理更加容易。html
表單組件支持幾個受用戶交互影響的屬性:java
value,用於<input>
,<textarea>
組件。react
checked,用於類型爲checkbox
或者radio
的 <input>
組件。git
selected,用於<option>
組件。github
在 HTML 中<textarea>
的值經過子節點設置;在 React 中則應該使用 value 代替。
表單組件能夠經過onChange
回調函數來監聽組件變化。當用戶作出如下交互時,onChange
執行並經過瀏覽器作出響應:segmentfault
<input>
或 <textarea>
的 value 發生變化時。瀏覽器
<input>
的 checked 狀態改變時。函數
<option>
的 selected 狀態改變時。性能
和全部 DOM 事件同樣,全部的 HTML 原生組件都支持 onChange 屬性,並且能夠用來監聽冒泡的 change 事件.
對於
<input>
和<textarea>
,onChange應當被用於取代DOM內置的onInput事件處理
設置了 value 的 <input>
是一個受限組件。 對於受限的 <input>
,渲染出來的 HTML 元素始終保持 value 屬性的值。
render: function() { return <input type="text" value="Hello!"/>; }
上面的代碼將渲染出一個值爲 Hello! 的 input 元素。用戶在渲染出來的元素裏輸入任何值都不起做用,由於 React 已經賦值爲 Hello!。若是想響應更新用戶輸入的值,就得使用 onChange 事件
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} />; }
初始值是狀態中的value。若是要取數據,可直接使用 var inputValue = this.state.value。
render: function() { return <input type="text" defaultValue={this.state.value}/>; }
一個可控組件並不保持本身的原始狀態;組件的呈現徹底基於屬性。
var Kekong = React.creatClass({ getInitialState:function(){ return { dada:'shuaige' } }, handleChange:function(e){ this.setState({ dada:e.target.value }); }, submitHandler:function(e){ e.preventDefault(); alert(this.state.dada); }, render:function(){ return <form onSubmit={this.submitHandler}> <input type="text" value={this.state.dada} onChange={this.handleChange} /> <button type="submit">speak</button> </form>; } }); ReactDOM.render(<Kekong />,document.body);
沒有設置value(或者設爲null) 的<input>
組件是一個不可控組件。這樣的話,組件中的數據和state中的數據並不對應,能夠說,組件的數據不可控。
render: function() { return <input type="text" />; }
上面的代碼將渲染出一個空值的輸入框,用戶輸入將當即反應到元素上。和受限元素同樣,使用 onChange 事件能夠監聽值的變化。
若是想給組件設置一個非空的初始值,可使用 defaultValue 屬性。 數據在這裏並無存貯在狀態中,而是寫在input中。
render: function() { return <input type="text" defaultValue="Hello!" />; }
若是要拿到input中的value,需先拿到其DOM節點,而後獲取其value值
var inputValue = React.findDOMNode(this.refs.input).value
上面的代碼渲染出來的元素和受限組件同樣有一個初始值,但這個值用戶能夠改變並會反應到界面上。
一樣,<input type="checkbox">
和<input type="radio">
支持defaultChecked屬性,<select>
支持設置defaultValue。
defaultValue
和defaultChecked
屬性只能在初始的render函數中使用,若是你要在隨後的render函數中更新value值,你須要使用可控組件。
var UnKekong = React.creatClass({ submitHandler:function(e){ e.preventDefault(); var helloUnke = React.findDOMNode(this.refs.helloUnke).value; alert(helloUnke); }, render:function(){ return <form onsubmit={this.submitHandler}> <input ref="helloUnke" type="text" defaultValue="Dada shuaige" /> <button type="submit">speak</button> </form>; } }) React.render(<Unkekong />,document.body);
注意,在試圖改變正常處理Checkbox和Radio input時,React用一個click事件來代替change事件。大多數狀況下,這種行爲與預期相同,除了調用preventDefault時。preventDefault從視覺上阻止瀏覽器更新input,即便checked被觸發。它能夠在移除調用preventDefault與用setTimeout來切換checked中起做用。
組件可控的優勢:
符合React的數據流,單向數據流,從state流向render輸出的結果。
數據存貯在state中,便於使用。
便於對數據進行處理
<label htmlFor="name">Name</label>
要注意for是js關鍵字,要寫成htmlFor。具體JSX語法在之間筆記中有介紹,傳送門:React.js學習筆記之JSX解讀。如今多數提示用input的placeholder屬性替代。
<input type="" onChange={this.handleChange}/>
<textarea onChange={this.handleChange}/>
<select onChange={this.handleChange}><option></option></select>
能夠去查看實例代碼,傳送門:React表單Demo
var MyForm = React.createClass({ getInitialState:function(){ return { username:'', gender:'man', checked:true }; }, handleUsernameChange:function(e){ this.setState({ username:e.target.value }); }, handlerGenderChange:function(e){ this.setState({ gender:e.target.value }); }, handleCheckedChange:function(e){ this.setState({ checked:e.target.checked }); }, submitHandler:function (e) { e.preventDefault(); console.log(this.state); }, render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">請輸入用戶名</label> <input type="text" onChange={this.handleUsernameChange} value={this.state.username} id="username"/> <br/> <select onChange={this.handlerGenderChange} value={this.state.gender}> <option value="man">男</option> <option value="woman">女</option> </select> <br/> <label htmlFor="checkbox">大大是帥哥嗎</label> <input type="checkbox" value="大大是帥哥" checked={this.state.checked} onChange={this.handleCheckedChange} id="checkbox"/> <button type="submit">提交</button> </form> } }); ReactDOM.render(<MyForm />,document.getElementById('reactDemo'));
onChange={this.handleChange}
如有多個元素要運用事件處理函數,常規的方法是編寫多個onChange事件。這麼寫的話會致使代碼維護比較困難而且也很是冗餘。更好的作法是把事件處理函數編寫爲一個。能夠採用bind複用和name複用這兩種方法。
handleChange:function(name,event){ ...... } onChagne={this.handleChange.bind(this,'input')}
書寫簡單,但須要對bind()
機制熟悉,性能相對要好。
能夠去查看實例代碼,傳送門:React表單Demo
var MyForm = React.createClass({ getInitialState:function(){ return { username:'', gender:'man', checked:true }; }, handleChange:function(name,event){ var newState={}; newState[name]=name=="checked"?event.target.checked:event.target.value; this.setState(newState); }, submitHandler:function (e) { e.preventDefault(); console.log(this.state); }, render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">請輸入用戶名</label> <input type="text" onChange={this.handleChange.bind(this,"username")} value={this.state.username} id="username"/> <br/> <select onChange={this.handleChange.bind(this,"gender")} value={this.state.gender}> <option value="man">男</option> <option value="woman">女</option> </select> <br/> <label htmlFor="checkbox">大大是帥哥嗎</label> <input type="checkbox" value="大大是帥哥" checked={this.state.checked} onChange={this.handleChange.bind(this,"checked")} id="checkbox"/> <button type="submit">提交</button> </form> } }); ReactDOM.render(<MyForm />,document.getElementById('reactDemo'));
handleChange:function(event){ var name = event.target.name } onChange={this.handleChange}
相比Bind寫法會少一些參數,在函數中須要讀取表單的name值,須要添加name屬性。
能夠去查看實例代碼,傳送門:React表單Demo
var MyForm = React.createClass({ getInitialState:function(){ return { username:'', gender:'man', checked:true }; }, handleChange:function(event){ var newState={}; newState[event.target.name]=event.target.name=="checked"?event.target.checked:event.target.value; this.setState(newState); }, submitHandler:function (e) { e.preventDefault(); console.log(this.state); }, render:function () { return <form onSubmit={this.submitHandler}> <label htmlFor="username">請輸入用戶名</label> <input type="text" name="username" onChange={this.handleChange} value={this.state.username} id="username"/> <br/> <select name="gender" onChange={this.handleChange} value={this.state.gender}> <option value="man">男</option> <option value="woman">女</option> </select> <br/> <label htmlFor="checkbox">大大是帥哥嗎</label> <input type="checkbox" value="大大是帥哥" checked={this.state.checked} onChange={this.handleChange} name="checked" id="checkbox"/> <button type="submit">提交</button> </form> } }); ReactDOM.render(<MyForm />,document.getElementById('reactDemo'));
自定義表單組件能讓咱們更好的使用組件,讓咱們更好的開發網頁。
自定義表單組件的緣由:
內因:表單自己具有特殊性:樣式統1、信息內聚、行爲固定
外因:本質上是組件的嵌套,組織和管理組件的一種方式
本文主要簡單介紹了表單組件的一些用法。