React Dependency Injection
Provides a dependency injection system for React using InversifyJS. Each service can inherit the class
ReactiveService<TState> to allow them to trigger component updates when their state changes, allowing for components to use service data in their render functions and respond to changes.
This package provides both a HOC and a
To define a service, you need to define a class similar to this:
You can then create an Inversify container with this service bound to it, and define a module that provides the provider component, HOC decorator, and the hook.
You can then consume the service from your components like so:
;;;// This is assuming that the container is set up using the TYPES// style from the InversifyJS docs.;;
injectComponent should be usable as a decorator, however TypeScript currently doesn't allow decorators to change the decorated definition's typing currently (since this function removes the injected props from the components typing). If you use babel and JSX/JS, then it should work fine (although I haven't tested this).
Once you have this set up, you can provide the container using the provider component:
You can map service states directly to props using the second param of
injectComponent, which takes in a function that receives all of the injected services, and return an object to map into props. Example:
Keep note, the services are injected regardless of whether you use the state mapper or not. It is mostly a helper to allow more direct access to service state & allow proper diffing in
Passing container as props directly
injectComponent decorator supports containers being passed directly as the prop
container, however, if you do this, note that you MUST bind the
StateTracker class like so:
// Import using a similar statement to this;// Bind the class manuallyStateTracker.bindToContainercontainer;
You need to do this whenever you do not use the
InjectionProvider component provided in
To use the hook, you can do something like the following:
// Imports from this module used in the example.;// Configure the container from somewhere.;// Create the React context.// You can also use the context returned from `createInjection` if you plan to// mix both kinds.;// If you use the provider directly, instead of the one given in `createInjection`,// then you need to remember to do the following.StateTracker.bindToContainercontainer;// Consume the services in the component.// If you define this object outside of the component,// it will be re-used for each render, and `useInjection`// will skip re-fetching the same services multiple times// (this is implmented via `useMemo`).// You can still use it inline if you want.
You can also use the
useInject function provided in
createInjection. Doing so would mean the App component would look like this: