1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【React】895- 使用 IOC 解耦 React 組件

        共 4436字,需瀏覽 9分鐘

         ·

        2021-03-14 08:46

        IOC(控制反轉)是一種編程思想,可以解耦組件,提高組件復用性。

        本文包括兩部分:

        1. 介紹IOC概念
        2. IOCReact中的應用

        IOC是什么

        讓我們來看個例子:

        我們有個士兵的類,在類內部會實例化一種武器:

        class Soldier {
          constructor() {
            // 這里我們實例化一把步槍
            this.weapon = new Rifle();
          }
          attack() {
            this.weapon.attack();
          }
        }

        士兵的武器應該是多種多樣的,但是在Soldier類內部依賴了Rifle。

        所以當我們想將武器從步槍換為手榴彈時,只能這樣改寫:

        // ...
        constructor() {
          // 這里我們實例化一把步槍
          // this.weapon = new Rifle();
          // 這里我們實例化一個手榴彈
          this.weapon = new Grenade();
        }
        // ...

        理想的狀態(tài)是:士兵不依賴具體的武器,彈藥庫里有什么武器,就用什么武器。

        在這種情況下,IOC作為彈藥庫,就派上了用場。

        讓我們來改寫代碼:

        第一步:DI(Dependency Injection)

        改寫的第一步是使士兵不依賴具體的武器,而是將武器作為依賴注入給士兵:

        class Soldier {
          // 將武器作為依賴注入
          constructor(weapon) {
            this.weapon = weapon;
          }
          attack() {
            this.weapon.attack();
          }
        }

        我們將武器的實例作為Soldier的參數(shù)傳入,于是可以如下調用:

        const s1 = new Soldier(new Rifle());
        const s2 = new Soldier(new Grenade());

        這一步被稱為DI(依賴注入)。

        第二步:IOC容器

        那么武器從哪兒來呢?接下來來打造我們的武器庫:

        class Armory {
          constructor() {
            this.weapon = null;
          }
          setWeapon(weapon) {
            this.weapon = weapon;
          }
          getWeapon() {
            return this.weapon;
          }
        }

        武器庫支持存武器(setWeapon)和取武器(getWeapon)。

        現(xiàn)在,士兵不依賴具體武器,只需要去武器庫取武器:


        const armory1 = new Armory();

        class Soldier {
          // 將武器作為依賴注入
          constructor(armory) {
            this.weapon = armory.getWeapon();
          }
          attack() {
            this.weapon.attack();
          }
        }

        改造前的依賴關系:

        士兵 --> 武器

        改造前原先應用(士兵)擁有依賴的完全控制權。

        改造后的依賴關系:

        士兵 --> 武器庫 <-- 武器

        改造后應用(士兵)與服務提供方(武器)解耦,他們通過IOC容器(武器庫)聯(lián)系。

        Demo也能看出IOCDI的關系:DI是實現(xiàn)IOC編程思想的一種方式。

        除了DI外,另一種實現(xiàn)方式是Dependency Lookup(依賴查找),簡稱DL。

        IOC與React

        React中,為組件傳遞的props就是一種DI實現(xiàn)。

        為了跨層級傳遞數(shù)據(jù),我們常使用Context API

        function Name({
          const {name} = useContext(nameContext);
          reutrn <h1>{name}</h1>;
        }

        context將依賴提供方(name)與依賴使用方(Name)隔離,可以看作是一種IOC實現(xiàn)。

        所以說,合理使用React可以充分利用IOC的思想解耦代碼邏輯。

        接下來我們看看專業(yè)的DI庫如何與React結合:

        InversifyJS

        InversifyJS[1]是一個強大、輕量的DI庫。

        首先我們實現(xiàn)依賴(武器的實現(xiàn)):

        // armory.ts
        import { injectable } from "inversify";

        export interface IArmory<T> {
          attack(): T;
        }

        @injectable()
        export class Armory implements IArmory<string{
          attack() {
            return "Rifle biubiubiu~";
          }
        }

        通過inversify提供的injectable decorator標記該class是可被注入的。

        接下來實現(xiàn)需求方(士兵的實現(xiàn)):

        import React from "react";
        import { IArmory } from "./armory";

        export class Soldier extends React.Component {
          private readonly Armory: IArmory<string>;

          render() {
            return <h1 onClick={() => this.armory.attack()}>I am a soldier</h1>;
          }
        }

        最后實例化IOC容器,連接需求方與依賴:


        import { Container } from "inversify";
        import { IArmory, Armory } from "./armory";

        // 實例化IOC容器
        export const container = new Container();
        // 將依賴方注入容器,其中armory為該依賴的ID
        container.bind<IArmory<string>>("armory").to(Armory);

        至此,完成一個React組件的簡單IOC。

        業(yè)務邏輯的更多依賴都可以通過注入IOC容器來實現(xiàn)解耦。

        Hooks同樣可以通過inversify完成IOC,參考Dependency injection in React using InversifyJS. Now with React Hooks[2]

        參考資料

        [1]

        InversifyJS: https://github.com/inversify/InversifyJS

        [2]

        Dependency injection in React using InversifyJS. Now with React Hooks: https://itnext.io/dependency-injection-in-react-using-inversifyjs-now-with-react-hooks-64f7f077cde6

        1. JavaScript 重溫系列(22篇全)
        2. ECMAScript 重溫系列(10篇全)
        3. JavaScript設計模式 重溫系列(9篇全)
        4. 正則 / 框架 / 算法等 重溫系列(16篇全)
        5. Webpack4 入門(上)|| Webpack4 入門(下)
        6. MobX 入門(上) ||  MobX 入門(下)
        7. 100+篇原創(chuàng)系列匯總

        回復“加群”與大佬們一起交流學習~

        點擊“閱讀原文”查看 100+ 篇原創(chuàng)文章


        瀏覽 64
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            男女粗暴进入 | 日本美女性爱视频 | 欧美极品jiizzhd欧美暴力 | 大香蕉999 | 欧美日韩免费中文 | 寡妇与男高潮hd片 | 91麻豆一区二区三区 | 伊人色综合欧美 | 男女互舔下面 | 成人无码AV电影 |