Dependency Injection in React

Tram Ho

Dependency Injection is a common pattern implemented in many frameworks and libraries. At a glance, React doesn’t seem to be. But really, React has support for built-in dependency injection, JSX, you must be using it.

Dependency Injection in short

Dependency Injection solves a common problem: “hardcoded dependencies” – that is, the dependencies are fixed hard in the code. When an object A depends on an object B and then create a second object, then the dependency cannot be changed (because it has been hardcode).

For example, the Calculator class creates a logger service, which is hard fixed as ConsoleLogger , and cannot be changed later:

However, when implementing this test class, developers want to “mock” this service logger component (no longer log out to the console, for example). Or when running production, they want to use SysLogger or another logger example of Sentry (SaaS logger) is not possible because the dependency has been hardcode.

We can solve the above problem with a commit using Dependency Injection as follows:

Now dependency no longer depends on when object A creates object B:

And so developers can easily change the dependency later:

Thanks to Dependency Injection, the code appears to be cleaner, more modularized. Angular has a buil-in Dependency Injection Container, so is Symfony and Spring . But it seems React.js doesn’t?

JSX supports Dependency Injection

React supports Dependency Injection without dependency injection containers (like Angular), thanks to JSX.

Take a look at component render product reviews in the table below:

Here is the code render table:

The <List> component retrieves data from the route /review/ in a REST API and passes a parameter as perPage . But <List> does not implement institute render table reviews. Instead, it lets the child components render: <DataGrid>. That means that <List> depends on <DataGrid> for the render, a paren-child relationship has been created here, Dependency Injection.

And like all other types of Dependency Injection, we can change the “dependency” very easily. For example, in the above example, if we want to change the render component to a “simple list” instead of a “data grid”, we just need to replace the child of <List> with another component:

React even allows injecting more than one dependency in an element. First, because an element can have more than one child. In the previous example, <DataGrid> received a list of columns to be displayed:

In addition to injecting with child components, we can also inject through props, as below we can also inject into another DataGrid body:

And since each dependency is a component, we can also inject the dependency into the dependency, like this:

Thus, JSX has got the basic features of a Dependency Injection Container: allowing moving, dynamically replacing dependencies and configuring them.

React Context

Above we saw the use of JSX to implement Dependency Injection in the JSX Template, so what about the service functions? React also encourages the use of components for services. For example, we can pass a translation service using the component’s props:

However these posts can be cumbersome if the code is large and has nested classes. So React provides another component to declare Dependency Injection as context :

Conclusion

Why doesn’t React provide a Dependency Injection Container like Angular? Simply because it is not necessary, JSX and context are more than enough to make React apps more modular and testable.

This is one of React’s strong points: even with large and large-scale applications, React can do everything well without requiring large and bulky frameworks (like Angular). ? ):

References

Share the news now

Source : Viblo