剛入門React,可能會因為React的單向數據流特性,遇到組件間通信的麻煩。下面的文章會給大家詳細介紹,開始前先來看壹張圖:
反應組件通信
需要組件間通信的幾種情況。
父組件與子組件通信。
子組件與父組件通信。
跨級組件通信
沒有嵌套關系的組件之間的通信。
1.父組件與子組件通信。
React數據流是單向的,父組件與子組件之間的通信也是最常見的。父組件通過props將所需的信息傳遞給子組件。
Child.jsx
從“React”導入React;
從“prop-types”導入PropTypes
導出默認函數子級({ name }) {
return & lth 1 & gt;您好,{ name } & lt/h 1 & gt;;
}
Child.propTypes = {
name:prop types . string . is必選,
};
Parent.jsx
從“react”導入React,{ Component };
從'導入子級。/Child ';
類父擴展組件{
render() {
返回(
& ltdiv & gt
& ltchild name = " Sara "/& gt;
& lt/div & gt;
);
}
}
導出默認父級;
2.子組件與父組件通信。
使用回調函數
使用自定義事件機制
回叫功能
實現可以通過點擊子組件中的隱藏組件按鈕隱藏自己的功能。
List3.jsx
從“react”導入React,{ Component };
從“prop-types”導入PropTypes
類別列表3擴展組件{
靜態屬性類型= {
hideConponent:prop types . func . is是必需的,
}
render() {
返回(
& ltdiv & gt
哈哈,我是List3
& ltbutton onClick = { this . props . hideconfonent } & gt;隱藏List3組件
& lt/div & gt;
);
}
}
導出默認列表3;
應用程序,jsx
從“react”導入React,{ Component };
從'導入列表3。/components/list 3 ';
導出默認類應用程序擴展組件{
構造器(...args) {
超級(...args);
this.state = {
isShowList3:假,
};
}
show component =()= & gt;{
this.setState({
isShowList3:沒錯,
});
}
hideconfonent =()= & gt;{
this.setState({
isShowList3:假,
});
}
render() {
返回(
& ltdiv & gt
& ltbutton onClick = { this . show component } & gt;顯示列表組件
{
this.state.isShowList3?
& ltlist 3 hideconfonent = { this . hideconfonent }/& gt;
:
空
}
& lt/div & gt;
);
}
}
觀察實現方法可以發現,它和傳統的回調函數是壹樣的,setState和回調函數通常是成對出現的,因為回調函數是傳統的轉換內部狀態的函數;
3.跨級組件通信
分層組件通過道具。
例如,為了在組件A和組件B之間進行通信,應該首先找到組件A和組件B的父組件。a先和C組件通信,C組件通過props和B組件通信。這時,組件C就扮演了中間件的角色。
使用上下文
Context是壹個全局變量,就像壹個大容器,可以在任何地方訪問。我們可以把要交流的信息放在上下文上,然後在其他組件中隨意獲取。
但是,React官方並不建議使用大量的上下文。雖然可以減少層層傳遞,但是當組件結構復雜的時候,我們不知道上下文是從哪裏來的。而且上下文是壹個全局變量,是導致應用混亂的罪魁禍首。
使用上下文
下面例子中的組件關系:ListItem是List的子組件,List是app的子組件。
ListItem.jsx
從“react”導入React,{ Component };
從“prop-types”導入PropTypes
類ListItem擴展組件{
//子組件聲明它要使用上下文。
靜態上下文類型= {
color: PropTypes.string,
}
靜態屬性類型= {
值:PropTypes.string,
}
render() {
const { value } = this.props
返回(
& lt李style = { { background:this . context . color } } & gt;
& ltspan & gt{ value } & lt/span>。
& lt/李& gt
);
}
}
導出默認列表項;
List.jsx
從'導入ListItem。/ListItem ';
類別列表擴展組件{
//父組件聲明它支持上下文。
靜態childContextTypes = {
color: PropTypes.string,
}
靜態屬性類型= {
list: PropTypes.array,
}
//提供函數返回對應的上下文對象。
getChildContext() {
返回{
顏色:'紅色',
};
}
render() {
const { list } = this.props
返回(
& ltdiv & gt
& ltul & gt
{
list.map((entry,index)= & gt;
& ltListItem key = { ` list-$ { index } `} value = { entry . text }/& gt;,
)
}
& lt/ul & gt;
& lt/div & gt;
);
}
}
導出默認列表;
app.jsx
從“react”導入React,{ Component };
從'導入列表。/組件/列表';
常量列表= [
{
文本:“主題1”,
},
{
文本:“主題2”,
},
];
導出默認類應用程序擴展組件{
render() {
返回(
& ltdiv & gt
& lt目錄
list={list}
/& gt;
& lt/div & gt;
);
}
}
4.無嵌套關系的組件通信
使用自定義事件機制
在componentDidMount事件中,如果組件安裝完成,則訂閱該事件;卸載組件時,取消訂閱componentWillUnmount事件中的事件;
以常見的發布/訂閱模式為例,使用瀏覽器版本的Node.js事件模塊來實現。
使用自定義事件。
下面例子中的組件關系:List1和List2沒有嵌套關系,App是它們的父組件;
實現這樣壹個功能:點擊List2中的壹個按鈕,改變List1中的信息顯示。
首先,您需要在項目中安裝events包:
npm安裝事件-保存
在src下新建壹個util目錄,並在其中構建壹個events.js。
從“事件”中導入{ event emitter };
導出默認的新event emitter();
list1.jsx
從“react”導入React,{ Component };
從'導入發射器'../util/events ';
類別列表擴展組件{
施工員(道具){
超級(道具);
this.state = {
消息:“列表1”,
};
}
componentidmount(){
//組件加載後聲明壹個自定義事件。
this . event emitter = emitter . addlistener(' change message ',(message)= & gt;{
this.setState({
消息,
});
});
}
componentWillUnmount() {
emitter . remove listener(this . event emitter);
}
render() {
返回(
& ltdiv & gt
{this.state.message}
& lt/div & gt;
);
}
}
導出默認列表;
List2.jsx
從“react”導入React,{ Component };
從'導入發射器'../util/events ';
類別列表2擴展組件{
handle click =(message)= & gt;{
emitter.emit('changeMessage ',message);
};
render() {
返回(
& ltdiv & gt
& ltbutton onClick = { this . handle click . bind(this,' list 2 ')} & gt;單擊I更改List1組件中顯示的信息
& lt/div & gt;
);
}
}
APP.jsx
從“react”導入React,{ Component };
從'導入列表1。/components/list 1 ';
從'導入列表2。/components/list 2 ';
導出默認類應用程序擴展組件{
render() {
返回(
& ltdiv & gt
& ltList1 />
& ltList2 />
& lt/div & gt;
);
}
}
自定義事件是典型的發布-訂閱模式,組件之間的通信是通過向事件對象添加偵聽器和觸發事件來實現的。
摘要
父組件與子組件通信:props
子組件和父組件之間的通信:回調函數/自定義事件
跨層組件通信:逐層組件傳遞props/context
沒有嵌套關系的組件之間的通信:自定義事件
在與組件溝通時,主要看業務的具體需求,選擇最合適的壹個;
當業務邏輯復雜到壹定程度,可以考慮引入Mobx、Redux等狀態管理工具。
摘要