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 useInjection
hook.
Example Guide
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.
// injection.ts; ;
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.; ;
Note: 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:
ReactDOM.render , element;
State mapping
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 componentDidUpdate(...)
.
Passing container as props directly
The 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 createInjection
.
Hook
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: