React IoC
Hierarchical Dependency Injection for React
Features
- Hierarchical Dependency Injection
- Can inject dependencies using React Hooks
- Automatically calls
.dispose()
on created class instances when Recat unmoutsProvider
component - Can work without decorators
- Supports lazy service registration with code splitting
- ES6, CommonJS and UMD bundles
- Declarations for TypeScript and Flow
- Type Safe even in JavaScript (with TypeScript
--checkJs
mode) - Tiny: only 1.1 KB (min+gzip)
Requirements: React 16.6 or greater, ES6 Map or Map polyfill.
Documentation
- @provider class decorator or HOC
- toClass binding
- toValue binding
- toFactory binding
- toExisting binding
- @registerIn class decorator
- @inject property decorator
- inject utility function
- useInstance React Hook
Example
;;; users = observablemap<number User>; posts = observablemap<number Post>; @inject dataContext: DataContext; @action { const post = id: ; thisdataContextposts; return post; } @observerComponent @inject postService: PostService; { // ... } @Component { // ... }
@provider (alias @Provider)
HOC (or decorator) that registers dependencies in scope of wrapped component.
; @Component { // ... }
Providers can be nested:
@Component { // ... } @Component { // ... }
Also Provider
component has static register()
function, for imperative dependencies registration:
// App.jsx; Component {} App;
// somewhere else; App;
@registerIn (alias @RegisterIn)
Class decorator for lazy service registration in Provider
. Accepts lambda that returns some Proveider
component.
// ./services/LazyService.jsimport registerIn from "react-ioc";import App from "../components/App"; @
// ./components/LazyWidget.jsximport inject from "react-ioc";import LazyService from "../services/LazyService"; Component @inject lazyService: LazyService;
// ./components/App.jsximport provider from "react-ioc";const LazyWidget = React; @Component { return <React.Suspense => <LazyWidget /> </React.Suspense> ; }
Also, is can accept binding as second argument:
// ./services/LazyService.jsimport registerIn toClass from "react-ioc";import App from "../components/App"; interface LazyService : void; implements LazyService // ... @
@inject (alias @Inject)
Property decorator for property dependency injection.
Can use dependency types from Reflect Metadata (with TypeScript --emitDecoratorMetadata
):
import inject from "react-ioc"; @inject barService: BarSerivce; Component @inject fooService: FooService; @inject barService: BarSerivce; // ...
Or manually specified dependencies:
import inject from "react-ioc"; @ barService; Component @ fooService; @ barService; // ...
inject
Utility function for property or constructor dependency injection. Note, that for React Components we should explicitely define static contextType = InjectorContext
(unlike with @inject
decorator).
Property Injection:
import inject InjectorContext from "react-ioc"; barService = ; Component fooService = ; barService = ; static contextType = InjectorContext;
Constructor Injection:
import inject from "react-ioc"; { thisfooService = fooService || ; thisbarService = barService || ; }
useInstance React Hook
import useInstance useInstances from "react-ioc"; const MyButton = { const myService = ; return <button =>Ok</button>} const MyWidget = { const fooService barService = ; return <div><MyButton /></div>}
Usage
> npm install --save react-ioc
UMD build
const provider inject = windowReactIoC;