1. 程式人生 > >react 父子元件之間的通訊和函式呼叫

react 父子元件之間的通訊和函式呼叫

reactjs是一枚新進小鮮肉,跟gulp搭配流行一段時間了。工作或者面試中經常遇到這樣的問題,“子元件如何向父元件傳值?”。其實很簡單,概括起來就是:react中state改變了,元件才會update。父寫好state和處理該state的函式,同時將函式名通過props屬性值的形式傳入子,子呼叫父的函式,同時引起state變化。子元件要寫在父元件之前。具體寫法看下面3個例子。

例子1.這裡如下圖,使用者郵箱為父,綠色框為子。 父元件為使用者輸入的郵箱設好state,即“{email: ''}”,同時寫好處理state的函式,即“handleEmail”,這兩個名稱隨意起;再將函式以props的形式傳到子元件,子元件只需在事件發生時,呼叫父元件傳過來的函式即可。 

//以下所有例子對應的html
<body>
    <div id="test"></div>
</body>
複製程式碼
//子元件
var Child = React.createClass({
    render: function(){
        return (
            <div>
                請輸入郵箱:<input onChange={this.props.handleEmail}/>
            </div>
        )
    }
});
//父元件,此處通過event.target.value獲取子元件的值
var Parent = React.createClass({ getInitialState: function(){ return { email: '' } }, handleEmail: function(event){ this.setState({email: event.target.value}); }, render: function(){ return ( <div> <div>使用者郵箱:{this
.state.email}</div> <Child name="email" handleEmail={this.handleEmail}/> </div> ) } }); React.render( <Parent />, document.getElementById('test') );
複製程式碼

例子2.有時候往往需要對資料做處理,再傳給父元件,比如過濾或者自動補全等等,下面的例子對使用者輸入的郵箱做簡單驗證,自動過濾非數字、字母和"@."以外的字元。

複製程式碼
//子元件,handleVal函式處理使用者輸入的字元,再傳給父元件的handelEmail函式
var Child = React.createClass({
    handleVal: function() {
        var val = this.refs.emailDom.value;
        val = val.replace(/[^0-9|a-z|\@|\.]/ig,"");
        this.props.handleEmail(val);
    },
    render: function(){
        return (
            <div>
                請輸入郵箱:<input ref="emailDom" onChange={this.handleVal}/>
            </div>
        )
    }
});
//父元件,通過handleEmail接受到的引數,即子元件的值
var Parent = React.createClass({
    getInitialState: function(){
        return {
            email: ''
        }
    },
    handleEmail: function(val){
        this.setState({email: val});
    },
    render: function(){
        return (
            <div>
                <div>使用者郵箱:{this.state.email}</div>
                <Child name="email" handleEmail={this.handleEmail}/>
            </div>
        )
    }
});
React.render(
  <Parent />,
  document.getElementById('test')
);
複製程式碼

例子3.如果還存在孫子元件的情況呢?如下圖,黑框為父,綠框為子,紅框為孫,要求子孫的資料都傳給爺爺。原理一樣的,只是父要將爺爺對孫子的處理函式直接傳下去。

複製程式碼
//孫子,將下拉選項的值傳給爺爺
var Grandson = React.createClass({
    render: function(){
        return (
            <div>性別:
                <select onChange={this.props.handleSelect}>
                    <option value="">男</option>
                    <option value="">女</option>
                </select>
            </div>
        )
    }
});
//子,將使用者輸入的姓名傳給爹  
//對於孫子的處理函式,父只需用props傳下去即可
var Child = React.createClass({
    render: function(){
        return (
            <div>
                姓名:<input onChange={this.props.handleVal}/>
                <Grandson handleSelect={this.props.handleSelect}/>
            </div>
        )
    }
});
//父元件,準備了兩個state,username和sex用來接收子孫傳過來的值,對應兩個函式handleVal和handleSelect
var Parent = React.createClass({
    getInitialState: function(){
        return {
            username: '',
            sex: ''
        }
    },
    handleVal: function(event){
        this.setState({username: event.target.value});
    },
    handleSelect: function(event) {
        this.setState({sex: event.target.value});
    },
    render: function(){
        return (
            <div>
                <div>使用者姓名:{this.state.username}</div>
                <div>使用者性別:{this.state.sex}</div>
                <Child handleVal={this.handleVal} handleSelect={this.handleSelect}/>
            </div>
        )
    }
});
React.render(
  <Parent />,
  document.getElementById('test')
);