寫在前面
雖然有一定的移動APP開發(fā)經(jīng)驗刻两,但RN技術我還是一個小白外恕,上一篇對路由等有了一定的了解,這篇文章將著重解決RN跨組件進行通信的方式学少。實現(xiàn)的效果是剪个,A界面跳轉(zhuǎn)B界面,B界面進行狀態(tài)的修改版确,然后A界面做出相應的數(shù)值變化扣囊。
效果展示
// 進入界面A
監(jiān)聽界面:componentWillMount
進行監(jiān)聽
// 進入界面B并發(fā)布消息
界面監(jiān)聽回傳值 傳遞數(shù)值
// 退出界面A
監(jiān)聽界面:componentWillUnmount
取消監(jiān)聽
ok就是如上日志的效果,生命周期開始注冊阀坏,然后結(jié)束的時候取消監(jiān)聽即可
EventBus源碼
class EventBus {
constructor() {
this.events = this.events || {};
}
}
//構(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ù)組存入對應的鍵名下
this.events[type] = [fun];
currentIndex = 0
} else { //如果注冊過士修,則直接放入
e.push(fun);
//獲取當前組件監(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ù),只移除當前組件監(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;
具體代碼使用
PageA 進行注冊
// 監(jiān)聽并設置狀態(tài)改變剛更新UI
componentWillMount(): void {
console.log('監(jiān)聽界面:componentWillMount');
console.log('進行監(jiān)聽');
this.subscribe = EventBus.addListener("notify", data => {
console.log("界面監(jiān)聽回傳值", data);
this.setState({
show:data
})
});
}
// 取消監(jiān)聽以放置重復注冊
componentWillUnmount(): void {
console.log('監(jiān)聽界面:componentWillUnmount');
console.log('取消監(jiān)聽');
EventBus.remove(this.subscribe);
}
PageB觸發(fā)
EventBus.emit('notify','傳遞數(shù)值');
好了如上就是全部的使用了
拓展
由于受了Android開發(fā)的影響侄榴,始終對EventBus情有獨鐘雹锣,應用vue也是如此,但我們也需要對其基本的父子組件通信的學習以及了解癞蚕,如props等父子通信是要會的蕊爵。這是我們通信學習的第一步,后面還需要對redux進行深入的學習桦山。既然開始了攒射,就一定要百分百的付出。
參考文章
React組件通信——Event Bus
React Native Event Bus,消息總線
React Native組件生命周期