小编给大家分享一下如何使用IOC解耦React组件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
IOC(控制反转)是一种编程思想,可以解耦组件,提高组件复用性。
IOC是什么
让我们来看个例子:
我们有个士兵的类,在类内部会实例化一种武器:
class Soldier { constructor() { // 这里我们实例化一把步枪 this.weapon = new Rifle(); } attack() { this.weapon.attack(); } }
士兵的武器应该是多种多样的,但是在Soldier类内部依赖了Rifle。
所以当我们想将武器从步枪换为手榴弹时,只能这样改写:
// ... constructor() { // 这里我们实例化一把步枪 // this.weapon = new Rifle(); // 这里我们实例化一个手榴弹 this.weapon = new Grenade(); } // ...
理想的状态是:士兵不依赖具体的武器,弹药库里有什么武器,就用什么武器。
在这种情况下,IOC作为弹药库,就派上了用场。
让我们来改写代码:
第一步:DI(Dependency Injection)
改写的第一步是使士兵不依赖具体的武器,而是将武器作为依赖注入给士兵:
class Soldier { // 将武器作为依赖注入 constructor(weapon) { this.weapon = weapon; } attack() { this.weapon.attack(); } }
我们将武器的实例作为Soldier的参数传入,于是可以如下调用:
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)。
现在,士兵不依赖具体武器,只需要去武器库取武器:
const armory1 = new Armory(); class Soldier { // 将武器作为依赖注入 constructor(armory) { this.weapon = armory.getWeapon(); } attack() { this.weapon.attack(); } }
改造前的依赖关系:
士兵 --> 武器
改造前原先应用(士兵)拥有依赖的完全控制权。
改造后的依赖关系:
士兵 --> 武器库 <-- 武器
改造后应用(士兵)与服务提供方(武器)解耦,他们通过IOC容器(武器库)联系。
从Demo也能看出IOC与DI的关系:DI是实现IOC编程思想的一种方式。
除了DI外,另一种实现方式是Dependency Lookup(依赖查找),简称DL。
IOC与React
在React中,为组件传递的props就是一种DI实现。
为了跨层级传递数据,我们常使用Context API:
function Name() { const {name} = useContext(nameContext); reutrn <h2>{name}</h2>; }
context将依赖提供方(name)与依赖使用方(Name)隔离,可以看作是一种IOC实现。
所以说,合理使用React可以充分利用IOC的思想解耦代码逻辑。
接下来我们看看专业的DI库如何与React结合:
InversifyJS
InversifyJS[1]是一个强大、轻量的DI库。
首先我们实现依赖(武器的实现):
// 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是可被注入的。
接下来实现需求方(士兵的实现):
import React from "react"; import { IArmory } from "./armory"; export class Soldier extends React.Component { private readonly Armory: IArmory<string>; render() { return <h2 onClick={() => this.armory.attack()}>I am a soldier</h2>; } }
最后实例化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。
业务逻辑的更多依赖都可以通过注入IOC容器来实现解耦。
Hooks同样可以通过inversify完成IOC。
以上是“如何使用IOC解耦React组件”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。