React 元件傳參
前幾天寫專案有用到React,現學現賣一下。React的思想其實就是就是元件化思想。自我感覺:就和Vue差不多,甚至比Vue還要嚴重的元件化,它將可以重用的部分進行元件化開發,形成一個個相對獨立的元件,那麼元件化後,你也會提出些疑問,元件與元件之間,將怎樣進行資訊的傳遞呢?下面來介紹下元件之間傳遞資訊的方法。
元件之間傳遞資訊方式,總體可分為以下5種:
1.(父元件)向(子元件)傳遞資訊
2.(父元件)向更深層的(子元件) 進行傳遞資訊 >>利用(context)
3.(子元件)向(父元件)傳遞資訊
4.沒有任何巢狀關係的元件之間傳值(比如:兄弟元件之間傳值)
5.利用react-redux進行元件之間的狀態資訊共享
下面結合例項詳細說明種傳遞資訊的方式。
以下的例子都是比較經典的例子,看過後加入了我的個人見解,希望對大家有所幫助。
一.(父元件)向(子元件)傳遞資訊 >>>主要是通過 prop進行傳值
來看下面的例子
以上這個例子,子元件通過 prop拿到了text值以及checked的屬性值;那麼當子元件要拿到祖父級元件的資訊,也是可以通過prop進行逐層的獲取。來看下下面的例子。
官方文件的示例程式碼如下:
以上的例子中第一層元件(MessageList)想要將color值傳遞到第三層元件(Button),通過第二層元件(Message)進行了傳遞。進而實現了。但是這種方式,並不是很優雅,如果傳遞的層級更多時,中間的層級都需要來傳遞,資料的傳遞變的更加繁瑣。所以我們就會想到,是否可以"越級"獲取資料。
這時 候就需要使用context。能幫你 "越級" 傳遞資料到元件中你想傳遞到的深層次元件中。
二.(父元件)向更深層的(子元件) 進行傳遞資訊 >>利用(context)
利用context,改進後的程式碼如下:
以上程式碼中通過新增 childContextTypes 和 getChildContext() 到 第一層元件MessageList ( context 的提供者),React 自動向下傳遞資料然後在元件中的任意元件(也就是說任意子元件,在此示例程式碼中也就是 Button )都能通過定義 contextTypes(必須指定context的資料型別) 訪問 context 中的資料。這樣就不需要通過第二層元件進行傳遞了。
指定資料並要將資料傳遞下去的父元件要定義 childContextTypes 和 getChildContext() ;想要接收到資料的子元件 必須定義 contextTypes 來使用傳遞過來的 context 。
三.(子元件)向(父元件)傳遞資訊
來看下面的例子
// 父元件
var MyContainer = React.createClass({
getInitialState: function () {
return {
checked: false
};
},
onChildChanged: function (newState) {
this.setState({
checked: newState
});
},
render: function() {
var isChecked = this.state.checked ? 'yes' : 'no';
return (
<div>
<div>Are you checked: {isChecked}</div>
<ToggleButton text="Toggle me" initialChecked={this.state.checked} callbackParent={this.onChildChanged} />
</div>
);
}
});
// 子元件
var ToggleButton = React.createClass({
getInitialState: function () {
return {
checked: this.props.initialChecked
};
},
onTextChange: function () {
var newState = !this.state.checked;
this.setState({
checked: newState
});
//這裡將子元件的資訊傳遞給了父元件
this.props.callbackParent(newState);
},
render: function () {
// 從(父元件)獲取的值
var text = this.props.text;
// 元件自身的狀態資料
var checked = this.state.checked;
//onchange 事件用於單選框與複選框改變後觸發的事件。
return (
<label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange} /></label>
);
}
});
以上例子中,在父元件繫結callbackParent={this.onChildChanged},在子元件利用this.props.callbackParent(newState),觸發了父級的的this.onChildChanged方法,進而將子元件的資料(newState)傳遞到了父元件。 這樣做其實是依賴 props 來傳遞事件的引用,並通過回撥的方式來實現的。
四.沒有任何巢狀關係的元件之間傳值(比如:兄弟元件之間傳值)
如果元件之間沒有任何巢狀關係,元件巢狀層次比較深,我們該怎樣去傳遞資訊呢?
下面來看一個例子
這個例子需要引入一個PubSubJS 庫,通過這個庫你可以訂閱的資訊,釋出訊息以及訊息退訂。 PubSubJS 具體可參考下面的內容http://blog.csdn.net/u011439689/article/details/51955991
// 定義一個容器(將ProductSelection和Product元件放在一個容器中)
var ProductList = React.createClass({
render: function () {
return (
<div>
<ProductSelection />
<Product name="product 1" />
<Product name="product 2" />
<Product name="product 3" />
</div>
);
}
});
// 用於展示點選的產品資訊容器
var ProductSelection = React.createClass({
getInitialState: function() {
return {
selection: 'none'
};
},
componentDidMount: function () {
//通過PubSub庫訂閱一個資訊
this.pubsub_token = PubSub.subscribe('products', function (topic, product) {
this.setState({
selection: product
});
}.bind(this));
},
componentWillUnmount: function () {
//當元件將要解除安裝的時候,退訂資訊
PubSub.unsubscribe(this.pubsub_token);
},
render: function () {
return (
<p>You have selected the product : {this.state.selection}</p>
);
}
});
var Product = React.createClass({
onclick: function () {
//通過PubSub庫釋出資訊
PubSub.publish('products', this.props.name);
},
render: function() {
return <div onClick={this.onclick}>{this.props.name}</div>;
}
});
ProductSelection和Product本身是沒有巢狀關係的,而是兄弟層級的關係。但通過在ProductSelection元件中訂閱一個訊息,在Product元件中又釋出了這個訊息,使得兩個元件又產生了聯絡,進行傳遞的資訊。所以根據我個人的理解,當兩個元件沒有巢狀關係的時候,也要通過全域性的一些事件等,讓他們聯絡到一起,進而達到傳遞資訊的目的。
五.利用react-redux進行元件之間的狀態資訊共享
如果是比較大型的專案,可以使用react-redux,這方面的資料可以參考阮一峰的網路日誌。 地址:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.
以上的例子,都可以實際嘗試一下。在實際專案中,可以根據實際的情況選取相應的解決辦法。最後,希望我的介紹能夠對你有所幫助。