(一)父子間組件通信:
?? 一般使用props静袖,回調(diào)函數(shù)進(jìn)行通信觉鼻。
(二)跨組件之間通信:
??(1)React Native提供了DeviceEventEmitter發(fā)事件、監(jiān)聽(比較重)
事件來完成父子間通信
??(2)閉包队橙,逐級透傳值(耦合度過高)
??(3)通過鍵值對存儲來達(dá)到事件總線的效果坠陈,從而達(dá)到父子之間解耦。
(三)優(yōu)缺點(diǎn)比較:
相比于發(fā)事件捐康、閉包傳值仇矾,采用鍵值對存儲來達(dá)到時間總線的效果更為輕量級,也完成了解耦解总。
(四)源碼如下:
/**
* 事件總線贮匕,使用鍵值對存儲
* @author zhengyixue
*/
class EventBus {
constructor() {
this.events = this.events || new Object();
}
}
//構(gòu)造函數(shù)需要存儲event事件
//發(fā)布事件,參數(shù)是事件的type和需要傳遞的參數(shù)
EventBus.prototype.emit = function (type, ...args) {
let e;
e = this.events[type];
// 查看這個type的event有多少個回調(diào)函數(shù)倾鲫,如果有多個需要依次調(diào)用粗合。
if (Array.isArray(e)) {
for (let i = 0; i < e.length; i++) {
e[i].apply(this, args);
}
} else {
e.apply(this, args);
}
};
//監(jiān)聽函數(shù),參數(shù)是事件type和觸發(fā)時需要執(zhí)行的回調(diào)函數(shù)
EventBus.prototype.addListener = function (type, fun) {
const e = this.events[type];
let currentIndex = -1
if (!e) { //如果從未注冊過監(jiān)聽函數(shù)乌昔,則將函數(shù)放入數(shù)組存入對應(yīng)的鍵名下
this.events[type] = [fun];
currentIndex = 0
} else { //如果注冊過,則直接放入
e.push(fun);
//獲取當(dāng)前組件監(jiān)聽函數(shù)壤追,在觀察函數(shù)數(shù)組中的索引磕道,移除監(jiān)聽時使用
currentIndex = this.events[type].length - 1
}
return { type, index: currentIndex}
};
//移除監(jiān)聽
EventBus.prototype.remove = function (subscribe) {
let { type, index } = subscribe
let e;
e = this.events[type];
// 查看這個type的event有多少個回調(diào)函數(shù),如果有多個需要依次調(diào)用行冰。
if (Array.isArray(e)) {
//監(jiān)聽的函數(shù)為空溺蕉,則空處理
if (e.length === 0) {
return
} else if (e.length === 1) {
//只有一個監(jiān)聽的函數(shù),則直接移除監(jiān)聽
e.splice(0, 1)
} else {
//如果同一個key存在多個監(jiān)聽函數(shù)悼做,只移除當(dāng)前組件監(jiān)聽函數(shù)
for (let i = 0; i < e.length; i++) {
if (index > 0 && i === index) {
e.splice(index, 1)
}
}
}
} else {
e = []
}
};
//移除所有監(jiān)聽
EventBus.prototype.removeAll = function () {
//移除所有監(jiān)聽函數(shù)
if (this.events.length > 0) {
this.events.length = 0;
}
};
const eventBus = new EventBus();
export default eventBus;
(五)用法:
(1)發(fā)事件:
EventBus.emit('key',value)
(2)接受事件:
this.subscribe = EventBus.addListener("key", data => {
console.log("message==", data);
this.setState({
data: data
});
});
(3)移除監(jiān)聽(componentWillUnmount):
EventBus.remove(this.subscribe)