In Angular.js it is possible to use dependency injection. I did some browsing and was not able to find an implementation of it. Does React have something similar to that?
The primary reason to use dependency injection in React, however, would be to mock and test React components easily. Unlike in Angular, DI is not a requirement while working with React, but rather a handy tool to use when you want to clean things up.
The three phases are: Mounting, Updating, and Unmounting.
Instead of passing props as an argument, we destructured and passed in the variables as the function's argument. Everything else remains the same. Note that you are not limited to just single variables as your props data – you can equally pass in functions and even data from objects.
React has IoC, but not any concept of a DI container like Angular. That is, instead of having a container that knows how to create objects and passing in dependencies, you pass them explicitly by passing props to the component when you instantiate it (like <MyComponent items={this.state.items} />
).
Passing dependencies as props isn't very common the React world though. Props are mostly used to pass data to components and not services/stores. But there's nothing stopping you from passing services/stores or even components as props (and certainly nothing wrong with it).
React has the concept of a context
which is a shared object for a whole tree of components. So the top level component can say that the context for its subtree has an object containing something like a UserStore, a MessageStore, etc. A component further down in the component hierarchy can then say that it wants access to the UserStore in its context. By saying that, the UserStore is accessible to that component without having to explicitly pass it down from the top component to the bottom, and the component requesting it doesn't know how it was created/passed to it.
It has the benefit of a DI container where you have a central place for object creation which can be passed in further down. Here's a good intro to contexts: https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
Contexts are still an undocumented feature of React, which means that its API can change in any coming versions of React, so you might want to use it sparsely until it becomes documented.
From react-in-patterns:
Most of the solutions for dependency injection in React components are based on context. I think that it's good to know what happens under the hood. As the time of this writing one of the most popular ways for building React apps involves Redux. The famous connect function and the Provider there use the context.
And from the react docs:
Context is an advanced and experimental feature. The API is likely to change in future releases.
Most applications will never need to use context. Especially if you are just getting started with React, you likely do not want to use context. Using context will make your code harder to understand because it makes the data flow less clear. It is similar to using global variables to pass state through your application.
If you have to use context, use it sparingly.
Regardless of whether you're building an application or a library, try to isolate your use of context to a small area and avoid using the context API directly when possible so that it's easier to upgrade when the API changes.
I have found a way to inject dependencies without using the context thanks to the usage of an IoC container.
Most containers support two kinds of injections:
Constructor injection: In order to use “constructor injection” the IoC container needs to be able to create the instances of the classes. In React the components sometimes are just functions (not classes) and we can’t delegate the creation of the instances of the components to the IoC container. This means that constructor injection powered by IoC containers don’t play nicely with React.
Property injection: Works nicely with React if what we want is to pass dependencies to components without passing them explicitly through each component.
I use InversifyJS as IoC container and it property injection support to pass dependencies to components without passing them explicitly through each component and without using the context:
import { pInject } from "./utils/di"; import { UserStore } from "./store/user"; class User extends React.Component<any, any> { @pInject(UserStore) private userStore: UserStore; // INJECTED! public render() { return ( <h1>{this.userStore.pageTitle}</h1> ); } }
The main advantage of using an IoC container like InversifyJS is that we are not using the context!
You can learn more about it here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With