「React Native」Event Bus,消息總線

(一)父子間組件通信:
?? 一般使用props,回調(diào)函數(shù)進(jìn)行通信。
(二)跨組件之間通信:
??(1)React Native提供了DeviceEventEmitter發(fā)事件、監(jiān)聽(比較重)
事件來完成父子間通信
??(2)閉包,逐級透傳值(耦合度過高)
??(3)通過鍵值對存儲來達(dá)到事件總線的效果,從而達(dá)到父子之間解耦。
(三)優(yōu)缺點(diǎn)比較:
相比于發(fā)事件、閉包傳值,采用鍵值對存儲來達(dá)到時(shí)間總線的效果更為輕量級,也完成了解耦。
(四)源碼如下:




/**
 * 事件總線,使用鍵值對存儲
 * @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];
    // 查看這個(gè)type的event有多少個(gè)回調(diào)函數(shù),如果有多個(gè)需要依次調(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ā)時(shí)需要執(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)聽時(shí)使用
        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];
    // 查看這個(gè)type的event有多少個(gè)回調(diào)函數(shù),如果有多個(gè)需要依次調(diào)用。
    if (Array.isArray(e)) {
        //監(jiān)聽的函數(shù)為空,則空處理
        if (e.length === 0) {
            return
        } else if (e.length === 1) {
            //只有一個(gè)監(jiān)聽的函數(shù),則直接移除監(jiān)聽
            e.splice(0, 1)
        } else {
            //如果同一個(gè)key存在多個(gè)監(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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容