【react】子組件向父組件傳值

reactjs是一枚新進小鮮肉,跟gulp搭配流行一段時間了。工做或者面試中常常遇到這樣的問題,「子組件如何向父組件傳值?」。其實很簡單,歸納起來就是:react中state改變了,組件纔會update。父寫好state和處理該state的函數,同時將函數名經過props屬性值的形式傳入子,子調用父的函數,同時引發state變化。子組件要寫在父組件以前。具體寫法看下面3個例子。html

例子1.這裏以下圖,用戶郵箱爲父,綠色框爲子。 父組件爲用戶輸入的郵箱設好state,即「{email: ''}」,同時寫好處理state的函數,即「handleEmail」,這兩個名稱隨意起;再將函數以props的形式傳到子組件,子組件只需在事件發生時,調用父組件傳過來的函數便可。 react

//如下全部例子對應的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.bind(this)}/>
            </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.bind(this)}/>
            </div>
        )
    }
});
React.render(
  <Parent />,
  document.getElementById('test')
);

例子3.若是還存在孫子組件的狀況呢?以下圖,黑框爲父,綠框爲子,紅框爲孫,要求子孫的數據都傳給爺爺。原理同樣的,只是父要將爺爺對孫子的處理函數直接傳下去。gulp

//孫子,將下拉選項的值傳給爺爺
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.bind(this)} handleSelect={this.handleSelect.bind(this)}/>
            </div>
        )
    }
});
React.render(
  <Parent />,
  document.getElementById('test')
);
相關文章
相關標籤/搜索