react-inject-props
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.14 • Public • Published

    react-inject-props

    Build Status npm version Dependency Status

    Inject props to your react component.

    💾 Installation

    npm i react inversify react-inject-props --save

    or

    yarn add react inversify react-inject-props

    with typescript, you should install the "reflect-metadata" package as well:

    npm i reflect-metadata --save or yarn add reflect-metadata

    ▶ Usage

    Decorators creation

    you can create decorators InjectProps and ProvideProps use createPropsDecorators function with a inversify container instance as the root container:

    import { Container } from 'inversify';
    import { createPropsDecorators } from 'react-inject-props';
     
    const container = new Container();
    const {InjectProps, ProvideProps, containerManager} = createPropsDecorators(container);

    if rootContainer not specified, createPropsDecorators will create it internally, you can take it from the function result:

    import { createPropsDecorators } from 'react-inject-props';
     
    const {InjectProps, ProvideProps, containerManager} = createPropsDecorators();
    const rootContainer = containerManager.rootNode.container;

    Class injection

    import { injectable } from 'inversify';
    import React from 'react';
    import { render } from 'react-dom';
     
    @injectable()
    class Service {
      greeting () {
        console.log('hello world');
      }
    }
     
    // or simply
    // @ProvideProps([
    //   Service
    // ])
    @ProvideProps([
      {provide: Service, useClass: Service}
    ])
    export class App extends React.Component {
      render () {
        return ...;
      }
    }
     
    interface PageProps {
      service?: Service;
    }
     
    @InjectProps({
      service: Service
    })
    export class Page extends React.Component<PageProps> {
      componentDidMount () {
        this.props.service!.greeting();
      }
      ...
    }
     
    render((
      <App>
        <Page/>
      </App>
    ), document.getElementById('root'));

    in Page component, we can access Service instance by this.props.service, because we bind Service to container at App component with ProvideProps decorator and "Inject" it as this.props.service by InjectProps.

    Value Injection

    interface AppConfig {
      siteName: string;
    }
     
    const AppConfigToken = Symbol('appConfig');
    const appConfig: AppConfig = {
      siteName: 'Github'
    };
     
    @ProvideProps([
      {provide: AppConfigToken, useValue: appConfig}
    ])
    export class App extends React.Component {
    }
     
    interface PageProps {
      appConfig?: AppConfig
    }
     
    @InjectProps({
      appConfig: AppConfigToken
    })
    export class Page extends React.Component<PageProps> {
      componentDidMount () {
        console.log(this.props.appConfig!.siteName);
      }
    }

    Factory Injection(dynamic value)

    @injectable()
    class Service {
      getConfig () {
        return {
          siteName: 'Github'
        };
      }
    }
    const AppConfigToken = Symbol('appConfig');
    function getAppConfig (service: Service) {
      return service.getConfig();
    }
     
    @ProvideProps([
      Service,
      {provide: AppConfigToken, useFactory: getAppConfig, deps: [Service]}
    ])
    export class App extends React.Component {
    }
     
    interface PageProps {
      appConfig?: AppConfig
    }
     
    @InjectProps({
      appConfig: AppConfigToken
    })
    export class Page extends React.Component<PageProps> {
      componentDidMount () {
        console.log(this.props.appConfig!.siteName);
      }
    }

    hierarchical injection

    we can use multiple ProvideProps decorators in different hierarchies to implement an hierarchical injection system.

    @injectable()
    class Service {
      id = Math.random();
    }
    @ProvideProps([
      Service
    ])
    class App extends React.Component {}
     
    @InjectProps({
      service: Service
    })
    class PageA extends React.Component {}
     
    @InjectProps({
      service: Service
    })
    class CompInPageA extends React.Component {}
     
    @ProvideProps([
      Service
    ])
    @InjectProps({
      service: Service
    })
    class PageB extends React.Component {}
     
     
    render((
      <App>
        <PageA>
          <CompInPageA/>
        </PageA>
        <PageB/>
      </App>
    ), ...);

    in the above example, PageA.props.service is equals to CompInPageA.props.service and difference to PageB.props.service, case PageB is reprovide a Service.

    Use existing provider if already bounded

    @ProvideProps([
      {provide: Service, useClass: Service, useExisting: true}
    ])
    class Comp extends React.Component { }
     
    render ((
      <App>
        <Comp/>
      </App>
    ), ...);

    if Service can be resolved in App's providers or rootContainer, the Service provider will be ignored.

    Get container instance

    import { Container } from 'inversify';
     
    interface CompProps {
      container: Container;
    }
     
    @ProvideProps([
      Service
    ])
    class Comp extends React.Component<CompProps> {
      componentDidMount () {
        const {container} = this.props;
        ...
      }
    }

    container of current component's hierarchy will also inject in component.props when use ProvideProps or InjectProps decorator.

    Use ContainerContext directly

    import { ContainerContext } from 'react-inject-props';
     
    // or
     
    import { createPropsDecorators } from 'react-inject-props';
    const {ContainerContext} = createPropsDecorators();
     
    // then use it in your component
     
    class Comp extends React.Component {
      render () {
        return (
          <ContainerContext.Provider value={xxx}>
            ...
              ...
                <ContainerContext.Consumer>
                  {(container: Container) => {
                    ...
                  }}
                </ContainerContext.Consumer>
              ...
            ...
          </ContainerContext.Provider>
        );
      }
    }

    Keywords

    none

    Install

    npm i react-inject-props

    DownloadsWeekly Downloads

    0

    Version

    1.0.14

    License

    MIT

    Unpacked Size

    71.3 kB

    Total Files

    26

    Last publish

    Collaborators

    • awaw00