react-ioc

Hierarchical Dependency Injection for React

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
react-ioc
198251.0.05 years ago6 years agoMinified + gzip package size for react-ioc in KB

Readme

React IoC
Hierarchical Dependency Injection for React Build Status Coverage Status GitHub license npm version

Features

Hierarchical Dependency Injection Can inject dependencies using React Hooks Automatically calls .dispose() on created class instances when Recat unmouts Provider 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

arch
@provider class decorator or HOC
* [toClass](#react-ioc-provider) binding
* [toValue](#react-ioc-provider) binding
* [toFactory](#react-ioc-provider) binding
* [toExisting](#react-ioc-provider) binding
@registerIn class decorator @inject property decorator inject utility function useInstance React Hook

Example

```js import React from "react"; import { provider, inject } from "react-ioc" import { obserbvable, action } from "mobx"; import { observer } from "mobx-react"; class DataContext { users = observable.map(); posts = observable.map(); } class PostService { @inject dataContext: DataContext; @action createPost(user: User) {
const post = new Post({ id: uniqueId() });
this.dataContext.posts.set(post.id, post);
return post;
} } @observer class PostEditor extends React.Component { @inject postService: PostService; render() {
// ...
} } @provider(DataContext, PostService) class App extends React.Component { render() {
// ...
} } ```

@provider (alias @Provider)

HOC (or decorator) that registers dependencies in scope of wrapped component. ```js import { provider, toClass, toFactory, toValue, toExisting } from "react-ioc"; @provider( DataContext, // bind DataContext to self IFooService, FooService // bind IFooService to FooService IBarService, toClass(BarService) // bind IBarService to BarService IBazService, toValue({ baz: 123 }) // bind IBazService to static value // bind MobxStore to factory with dependencies MobxStore, toFactory(
[IFooService, IBarService],
(fooService, barService) => MobxStore.create(fooService, barService)
)
// bind IObsoleteService to already registered IFooService instance IObsoleteService, toExisting(IFooService), ) class App extends React.Component { render() {
// ...
} } ``` Providers can be nested: ```js @provider(DataContext, AuthService) class App extends React.Component { render() {
// ...
} } @provider(UserService) class HomePage extends React.Component { render() {
// ...
} } ``` Also Provider component has static register() function, for imperative dependencies registration: ```js // App.jsx import { provider, toClass } from "react-ioc"; class App extends React.Component {} export default provider()(App); ``` ```js // somewhere else import App from "./App"; App.register(FooService, BarService, toClass(BarService)); ``` ▲ back to top ▲

@registerIn (alias @RegisterIn)

Class decorator for lazy service registration in Provider. Accepts lambda that returns some Proveider component. ```jsx // ./services/LazyService.js import { registerIn } from "react-ioc"; import App from "../components/App"; @registerIn(() => App) export class LazyService {} ``` ```jsx // ./components/LazyWidget.jsx import { inject } from "react-ioc"; import { LazyService } from "../services/LazyService"; export default class LazyWidget extends React.Component { @inject lazyService: LazyService; } ``` ```jsx // ./components/App.jsx import { provider } from "react-ioc"; const LazyWidget = React.lazy(() => import("./LazyWidget")); @provider() export default class App extends React.Component { render() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<LazyWidget />
</React.Suspense>
);
} } ``` Also, is can accept binding as second argument: ```jsx // ./services/LazyService.js import { registerIn, toClass } from "react-ioc"; import App from "../components/App"; interface LazyService { method(): void; } class LazyServiceImpl implements LazyService { // ... } @registerIn(() => App, toClass(LazyServiceImpl)) export class LazyService {} ``` ▲ back to top ▲

@inject (alias @Inject)

Property decorator for property dependency injection. Can use dependency types from Reflect Metadata (with TypeScript --emitDecoratorMetadata): ```jsx import { inject } from "react-ioc"; class FooService { @inject barService: BarSerivce; } class MyComponent extends React.Component { @inject fooService: FooService; @inject barService: BarSerivce; // ... } ``` Or manually specified dependencies: ```jsx import { inject } from "react-ioc"; class FooService { @inject(BarSerivce) barService; } class MyComponent extends React.Component { @inject(FooService) fooService; @inject(BarSerivce) barService; // ... } ``` ▲ back to top ▲

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: ```jsx import { inject, InjectorContext } from "react-ioc"; class FooService { barService = inject(this, BarSerivce); } class MyComponent extends React.Component { fooService = inject(this, FooService); barService = inject(this, BarSerivce); static contextType = InjectorContext; } ``` Constructor Injection: ```jsx import { inject } from "react-ioc"; class OtherService { constructor(fooService, barService) {
this.fooService = fooService || inject(this, FooService);
this.barService = barService || inject(this, BarSerivce);
} } ``` ▲ back to top ▲

useInstance React Hook

```jsx import { useInstance, useInstances } from "react-ioc"; const MyButton = props => { const myService = useInstance(MyService); return myService.doSomething()}>Ok } const MyWidget = props => { const fooService, barService = useInstances(FooService, BarService); return
} ``` ▲ back to top ▲

Usage

```
npm install --save react-ioc
```

UMD build

```html ``` ```js const { provider, inject } = window.ReactIoC; ```