国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

react 中發布訂閱模式使用

UsherChen / 1716人閱讀

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

react 中發布訂閱模式使用 場景

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

場景一

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

方案一:
將這份數據作為公共的數據 data,A B 模塊同時使用并更改這份數據這一份數據。若使用 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 結構上不同,但是存在業務上的聯系: 當 data1 更新后需要 data2 更新;data2 更新同樣需要 data1 同步;對應后端的兩個不同的 API。

我們整理一下

A B 使用兩份存在聯系的 data

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

兩份 data 對應不同的 API 接口

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

方案一

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

如果你使用了 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 可以實現功能,在模塊 B 內調用模塊 A 的更新邏輯;但這樣邏輯就耦合了,我在模塊 A 調用模塊 B 方法 在模塊 B 調用模塊 A 的方法;但很有可能這兩個模塊是沒有其他交互的。這違反了低耦合高內聚的原則
而且書寫 redux 的一個原則就是 不要調用(dispatch)其他模塊的 action

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

方案二:利用事件系統

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

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();

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

發布:當A模塊內數據因操作發生變化時,觸發該數據變化的事件,定義typedata1Change

注冊:這里B模塊的注冊的時機,上述的場景為A和B模塊可能同時出現,所以A模塊存在B模塊卻不存在。所以這個B模塊事件的監聽選擇在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())
    }
}

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

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

其他方案歡迎大家評論

其他場景

待大家補充

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

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

相關文章

  • Redux入門0x101: 簡介及`redux`簡單實現

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

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

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

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

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

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

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

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

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

    firim 評論0 收藏0

發表評論

0條評論

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