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?
相关问题
- How to toggle on Order in ReactJS
- Refreshing page gives Cannot GET /page_url in reac
- Adding a timeout to a render function in ReactJS
- React Native Inline style for multiple Text in sin
- angularJS: ui-router equivalent to $location.searc
相关文章
- Why would we use useEffect without a dependency ar
- Passing variable through URL with angular js
- Is it possible to get ref of props.children?
- Stateless function components cannot be given refs
- React testing library: Test attribute / prop
- Watch entire object (deep watch) with AngularJS
- React/JestJS/Enzyme: How to test for ref function?
- Angular ng-if change span text
I don't really like using contexts, since it's still an experimental feature of react and kind of bulky. I've also looked at DI frameworks like
react-di
but it required each component to be aware of the DI framework's way of injecting dependencies (i.e. knowing that the dependency is in thethis.props.di
object.).If we rule out contexts, the canonical way to inject something into a React component is through the use of props. The props are injected when you run
React.createElement
, i.e. for each jsx tag. TheReact.createElement
function takes a component, some props and some children and returns a React element. I.e.(component, props, children) -> element
.I made a
createComponent
function with almost the same signature asReact.createElement
but which returns a component instead, i.e.(component, props, children) -> component
. Here it is:The returned component can be injected in a prop, like in this example:
Fiddle: https://jsfiddle.net/8971g8s5/3/
The good thing about this is that
PropTypes
will still work very well, so each component can clearly declare what kind of properties it wants.Also, the receiving end of the injection doesn't need to depend on any special implementation, just the normal props system of React. So the components needn't know that you're using dependency injection or how you do it, they just care about what props they receive.
From react-in-patterns:
And from the react docs:
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:
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.
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.