成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

react 中發(fā)布訂閱模式使用

UsherChen / 1726人閱讀

摘要:中發(fā)布訂閱模式使用場景怎么能將設計模式應用到我們的項目中以前一直在思考這個問題。兩個模塊在事件系統(tǒng)唯一的聯(lián)系就是事先定義好事件的。

react 中發(fā)布訂閱模式使用 場景

怎么能將設計模式應用到我們的 React 項目中?以前一直在思考這個問題。

場景一

模塊 A 模塊 B 需要用到同一個數(shù)據(jù) data,A 和 B 都會修改這份數(shù)據(jù),且這兩個模塊會同時存在;這時我們如何做到數(shù)據(jù)公用與各個模塊的更新?

方案一:
將這份數(shù)據(jù)作為公共的數(shù)據(jù) data,A B 模塊同時使用并更改這份數(shù)據(jù)這一份數(shù)據(jù)。若使用 redux 代碼可能是這樣:

// store

const store = {
    common: { data: [] },
    A: {},
    B: {},
};

// reducer
function commonReducer(state = { data: [] }, action) {
    switch (action.type) {
        case "common_setData": {
            return {
                ...state,
                data: action.data,
            };
        }
        default:
            return state;
    }
}

// connect

const actionCreator = () => {};

connect(({ A, common }) => ({ ...A, data: common.data }))(A);
connect(({ B, common }) => ({ ...A, data: common.data }))(B);

// change
// A B change調用方法;
this.props.dispatch({
    type: "common_setData",
    data: [1, 2],
});

好的,第一種場景可以使用 redux 完美解決

方案二:待補充

場景二

A 模塊使用了 data1, B 模塊使用了 data2;A B 模塊可以修改對應的 data;這兩份 data 結構上不同,但是存在業(yè)務上的聯(lián)系: 當 data1 更新后需要 data2 更新;data2 更新同樣需要 data1 同步;對應后端的兩個不同的 API。

我們整理一下

A B 使用兩份存在聯(lián)系的 data

其中一個更新需要另一個更新

兩份 data 對應不同的 API 接口

A B 對應兩個不同的 tab 且可能同時存在

方案一

當其中一個數(shù)據(jù)因操作發(fā)生更新時,判斷另一個模塊是否存在 如果存在則調用他的數(shù)據(jù)更新邏輯;

如果你使用了 redux,可能方便一點:

// reducerA
// 省略B
function reducerA(state = { data: [] }, action) {
    switch(action.type) {
        case "A_setDataA": {
            return {
                ...state,
                data: action.data
            }
        }
        default: return state
    }
}

// 假設使用了thunk中間件
const queryA = () => async (dispatch, getState) => {
    const dataA = await API.queryA()
    dispatch({
        type: "A_setDataA"
        data: dataA
    })
}

// page

class B extends React.Component {
    handleUpdateData = () => {
        // 如果 A模塊存在
        const { isAExistFlag, dispatch, queryA, queryB } = props
        dispatch(queryB())
        if (isAExistFlag) {
            dispatch(queryA())
        }
    }
}

這樣利用了 redux 可以實現(xiàn)功能,在模塊 B 內調用模塊 A 的更新邏輯;但這樣邏輯就耦合了,我在模塊 A 調用模塊 B 方法 在模塊 B 調用模塊 A 的方法;但很有可能這兩個模塊是沒有其他交互的。這違反了低耦合高內聚的原則
而且書寫 redux 的一個原則就是 不要調用(dispatch)其他模塊的 action

如果你不使用 redux 如果是一個模塊內調用其他模塊的方法也是沒有做到解耦的;那如何做到解耦尼?請看方案二

方案二:利用事件系統(tǒng)

如果您的項目中沒有一個全局的事件系統(tǒng),可能需要引入一個;一個簡單的事件系統(tǒng)大概是:

class EventEmitter {
    constructor() {
        this.listeners = {};
    }

    on(type, cb, mode) {
        let cbs = this.listeners[type];
        if (!cbs) {
            cbs = [];
        }
        cbs.push(cb);
        this.listeners[type] = cbs;
        return () => {
            this.remove(type, cb);
        };
    }

    emit(type, ...args) {
        console.log(
            `%c event ${type} be triggered`,
            "color:rgb(20,150,250);font-size:14px",
        );
        const cbs = this.listeners[type];
        if (Array.isArray(cbs)) {
            for (let i = 0; i < cbs.length; i++) {
                const cb = cbs[i];
                if (typeof cb === "function") {
                    cb(...args);
                }
            }
        }
    }

    remove(type, cb) {
        if (cb) {
            let cbs = this.listeners[type];
            cbs = cbs.filter(eMap => eMap.cb !== cb);
            this.listeners[type] = cbs;
        } else {
            this.listeners[type] = null;
            delete this.listeners[type];
        }
    }
}

export default new EventEmitter();

這個事件系統(tǒng)具有注冊,發(fā)布,移除事件的功能。那我們怎么在剛才這個場景去使用它尼?

發(fā)布:當A模塊內數(shù)據(jù)因操作發(fā)生變化時,觸發(fā)該數(shù)據(jù)變化的事件,定義typedata1Change

注冊:這里B模塊的注冊的時機,上述的場景為A和B模塊可能同時出現(xiàn),所以A模塊存在B模塊卻不存在。所以這個B模塊事件的監(jiān)聽選擇在B模塊組件的componentDidMount的時候注冊,在componentWillUnmount時移除

大致的代碼如下:

import EventEmitter from "eventEmitter"
class A extends React.Component {
    handleUpdateData = () => {
        // 如果 A模塊存在
        const { dispatch, queryB } = props
        dispatch(queryA())
        EventEmitter.emit("data1Change")
    }
}

// B
import EventEmitter from "eventEmitter"
class B extends React.Component {
    componentDidMount() {
        const unlistener = EventEmitter.on("data1Change", this.handleData1Change)
    }

    componentWillUnmount() {
        EventEmitter.on("data1Change", this.handleData1Change)
    }

    handleData1Change = () => {
        const { dispatch, queryB } = this.props
        dispatch(queryB())
    }
}

這樣通過事件系統(tǒng)做到了兩個模塊之間的解耦,作為事件發(fā)布方只管發(fā)布自己的事件。兩個模塊在事件系統(tǒng)唯一的聯(lián)系就是事先定義好事件的type。

不過這也增加了幾行的代碼量,但相比帶來的優(yōu)勢來說可以不計。

其他方案歡迎大家評論

其他場景

待大家補充

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/99573.html

相關文章

  • Redux入門0x101: 簡介及`redux`簡單實現(xiàn)

    摘要:在我看來它們的關系不會比共用開頭更深了,所以我就重新開了一個頭,但其實是基于前面寫的資源中文文檔英文文檔官方視頻學習歷程當初為了學習,看了許多的材料,中途曾經(jīng)放棄兩次,但是最后還是勇敢的拿起了它,現(xiàn)在終于勉強弄懂。 0x000 概述 這一章開始講redux,其實是承接前面的react,但其實作為一個框架來說,redux和react并沒有太多的關系,本身是獨立存在的。在我看來它們的關系不...

    ssshooter 評論0 收藏0
  • 翻譯 Meteor React 制作 Todos - 11 - 發(fā)布訂閱

    摘要:通過發(fā)布訂閱模式過濾數(shù)據(jù)現(xiàn)在我們已經(jīng)把應用中比較敏感的代碼放到了一些方法里面,我們還需要學習安全故事的另一半內容了。當在客戶端被調用時傳入發(fā)布器名稱,客戶端將會從發(fā)布器訂閱所有的數(shù)據(jù)。這個按鈕應該只是給任務的所有者來顯示。 通過發(fā)布訂閱模式過濾數(shù)據(jù) 現(xiàn)在我們已經(jīng)把應用中比較敏感的代碼放到了一些方法里面,我們還需要學習Meteor安全故事的另一半內容了。到現(xiàn)在為止,我們一直是假設整個整個...

    用戶83 評論0 收藏0
  • 解密傳統(tǒng)組件間通信與React組件間通信

    摘要:同時吸取了社區(qū)大量優(yōu)秀思想,進行歸納比對。有興趣的讀者可以點擊下面的鏈接購買,再次感謝各位的支持與鼓勵懇請各位批評指正京東當當原文網(wǎng)址 在React中最小的邏輯單元是組件,組件之間如果有耦合關系就會進行通信,本文將會介紹React中的組件通信的不同方式 通過歸納范,可以將任意組件間的通信歸類為四種類型的組件間通信,分別是父子組件,爺孫組件,兄弟組件和任意組件,需要注意的是前三個也可以算...

    CoderBear 評論0 收藏0
  • 源碼解析 —— Vue的響應式數(shù)據(jù)流

    摘要:下面我們會向大家解釋清楚為什么這個這么重要,以及它和的響應式數(shù)據(jù)流有什么關系。源碼前面鋪墊這么多就是希望大家能理解接下來要講的響應式數(shù)據(jù)流??偨Y講到這里大家應該都能夠明白的響應式數(shù)據(jù)流是如何實現(xiàn)的。 Vue、React介紹 目前前端社區(qū)比較推崇的框架有Vue 和 React,公司內部許多端都自發(fā)的將原有的老技術方案(widget + jQuery)遷移到 Vue / React上了。我...

    LuDongWei 評論0 收藏0
  • Vue基本原理

    摘要:標簽添加監(jiān)聽事件文本節(jié)點這一步我們操作頁面輸入框,可以看到以下效果,證明監(jiān)聽事件添加有效。 前言 經(jīng)過幾天的研究,發(fā)現(xiàn)學習框架的底層技術,收獲頗豐,相比只學習框架的使用要來的合算;如果工作急需,快速上手應用,掌握如何使用短期內更加高效;如果有較多的時間來系統(tǒng)學習,建議研究一下框架的等層技術、原理。 Vue、React、Angular三大框架對比 1、Vue Vue是尤雨溪編寫的一個構建...

    firim 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<