React.js學習筆記之表單詳解

React.js學習筆記之表單詳解

@(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} />;
 }

Default Value

初始值是狀態中的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 事件能夠監聽值的變化。

Default Value

若是想給組件設置一個非空的初始值,可使用 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。

defaultValuedefaultChecked屬性只能在初始的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的潛在問題

注意,在試圖改變正常處理Checkbox和Radio input時,React用一個click事件來代替change事件。大多數狀況下,這種行爲與預期相同,除了調用preventDefault時。preventDefault從視覺上阻止瀏覽器更新input,即便checked被觸發。它能夠在移除調用preventDefault與用setTimeout來切換checked中起做用。

Why use Controlled Components

組件可控的優勢:

  • 符合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複用這兩種方法。

bind複用

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'));

name複用

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'));

自定義表單組件

自定義表單組件能讓咱們更好的使用組件,讓咱們更好的開發網頁。

why 自定義表單組件?

自定義表單組件的緣由:

  • 內因:表單自己具有特殊性:樣式統1、信息內聚、行爲固定

  • 外因:本質上是組件的嵌套,組織和管理組件的一種方式

小結

本文主要簡單介紹了表單組件的一些用法。

特別感謝

相關文章
相關標籤/搜索