The application of IOC idea in React (dependency injection)

IOC(Inversion of Control) is a programming idea that can decouple components and improve component reusability.
This article consists of two parts:

  1. Introduction to IOCConcepts
  2. IOCReactapplications in

What is IOC?
Inversion of Control ( Inversion of Control, abbreviated as IoC) is a design principle in object-oriented programming that can be used to reduce the coupling between computer codes. The most common way is Dependency Injection ( Dependency Injection, DI for short).
With inversion of control, objects are passed references to the objects they depend on when they are created by an external entity that governs all objects in the system. It can also be said that dependencies are injected into objects.
Generally, this concept is mentioned more in Java, but in the front-end field, it seems that this concept is rarely mentioned. In fact, using this idea well can help our components decoupling no matter in the front-end and back-end.
"Dependency Injection" is actually a manifestation of the "Dependency Inversion Principle".
Dependency Inversion:

  1. Upper-level modules should not depend on lower-level modules, they should depend on a common abstraction.
  2. Abstractions should not depend on details, and details should depend on abstractions.


Let's take an example:
we have a soldier class, and inside the class we instantiate a weapon:


Soldiers' weapons should be varied, but Soldierdepended on within the class Rifle.
So when we want to change the weapon from a rifle to a grenade, we can only rewrite it like this:




理想的状态是:士兵不依赖具体的武器,弹药库里有什么武器,就用什么武器。
在这种情况下,IOC作为弹药库,就派上了用场。
让我们来改写代码:
第一步:DI(Dependency Injection)
改写的第一步是使士兵不依赖具体的武器,而是将武器作为依赖注入给士兵:



我们将武器的实例作为Soldier的参数传入,于是可以如下调用:



这一步被称为DI(依赖注入)。
第二步:IOC容器
那么武器从哪儿来呢?接下来来打造我们的武器库:


武器库支持存武器(setWeapon)和取武器(getWeapon)。
现在,士兵不依赖具体武器,只需要去武器库取武器:



改造前的依赖关系:
士兵 --> 武器
改造前原先应用(士兵)拥有依赖的完全控制权。
改造后的依赖关系:
士兵 --> 武器库 <-- 武器
改造后应用(士兵)与服务提供方(武器)解耦,他们通过IOC容器(武器库)联系。
Demo也能看出IOCDI的关系:DI是实现IOC编程思想的一种方式。
除了DI外,另一种实现方式是Dependency Lookup(依赖查找),简称DL
为啥需要依赖注入?
依赖注入(更广泛地说就是控制反转)主要用来解决下面几个问题:

  • 模块解耦 - 在代码设计中应用,强制保持代码模块分离。
  • 更好的可复用性 - 让模块复用更加容易。
  • 更好的可测试性 - 通过注入模拟依赖可以更方便测试。

其实, React 本身也内置了对依赖注入的支持。
IOC与React
React中,为组件传递的props就是一种DI实现。
为了跨层级传递数据,我们常使用Context API



context将依赖提供方(name)与依赖使用方(Name)隔离,可以看作是一种IOC实现。
所以说,合理使用React可以充分利用IOC的思想解耦代码逻辑。
接下来我们看看专业的DI库如何与React结合:
InversifyJS
InversifyJS[1]是一个强大、轻量的DI库。



首先我们实现依赖(武器的实现):


通过inversify提供的injectable decorator标记该class是可被注入的。
接下来实现需求方(士兵的实现):


IOC\


至此,完成一个React组件的简单IOC
业务逻辑的更多依赖都可以通过注入IOC容器来实现解耦。

下面我们再来看看几个 InversifyJS 的扩展库。

inversify-inject-decorators

该工具库主要提供了 lazyInject 之类的方法,它可以给出了一个惰性的注入,意思是在对象初始化时不需要提供依赖,当我们没办法改构造函数时,这个库就派上用场啦。

另外,除了字面上所说的惰性,另外一个非常重要的功能就是允许你将 inversifyJs 集成到任何自己控制类实例创建的库或者框架,比如 React 。

下面是一个 @lazyInject 的使用示例:

inversify-react

inversify-react 是一个唯一执行依赖注入的库。就像使用 React Context.Provider一样,我们从这个库也能拿到一个 Provider

然后我们就能在子组件中使用依赖了:

react-inversify

虽然和上一个库名字很像,但是两个库的做法是不一样的,这种方法更接近于 React 的思想,因为对象是作为属性传递的,而不是在组件内部实例化。

结实好友

喜欢结交一些和我一样处于前端进阶的朋友,有时候一个人的路不好走,多人一起走才有意思。链接

Guess you like

Origin juejin.im/post/7079612337111924772