Use any ioc library (tsyringe, inversify, @Moln/react-ioc, etc.) in react.
Install by npm
npm install --save @moln/react-ioc
or install with yarn
(this project is developed using yarn
)
yarn add @moln/react-ioc
class Foo { name = 'foo' }
class Bar { name = 'bar' }
const container = new DependencyContainer();
container.registerSingleton(Foo);
container.registerSingleton('MyBar', Bar);
render(
<DependencyContainerProvider container={container}>
<App />
</DependencyContainerProvider>,
document.createElement('app')
);
Use tsyringe
import {container, injectable} from "tsyringe";
// For implement `ContainerInterface`
container.get = container.resolve;
@injectable()
class Foo { name = 'foo' }
@injectable()
class Bar { name = 'bar' }
render(
<DependencyContainerProvider container={container as ContainerInterface}>
<App />
</DependencyContainerProvider>,
document.createElement('app')
);
Use inversify
import {Container, injectable} from "inversify";
const container = new Container();
@injectable()
class Foo { name = 'foo' }
@injectable()
class Bar { name = 'bar' }
render(
<DependencyContainerProvider container={container as ContainerInterface}>
<App />
</DependencyContainerProvider>,
document.createElement('app')
);
type BazProps = { foo: Foo; bar: Bar };
class BazComponent extends Component<BazProps> {
render() {
const {foo, bar} = this.props;
return <div>hello {foo.name}! {bar.name}! </div>;
}
}
const WrapperdBazComponent = injectServices({
foo: Foo,
bar: Bar,
})(BazComponent);
render(
<DependencyContainerProvider container={container}>
<WrapperdBazComponent />
</DependencyContainerProvider>,
document.createElement('app')
);
// By custom factory
const WrapperdBazComponent = injectServices((container, props) => {
return {
foo: container.get(Foo),
bar: porps.bar || container.get(Bar),
}
})(BazComponent);
render(
<DependencyContainerProvider container={container}>
<WrapperdBazComponent bar={new Bar} />
</DependencyContainerProvider>,
document.createElement('app')
);
const BazComponent = () => {
const foo = useService(Foo);
const bar = useService(Bar);
return <div>{foo.name} {bar.name}</div>;
};
render(
<DependencyContainerProvider container={container}>
<BazComponent />
</DependencyContainerProvider>,
document.createElement('app')
);
Modify your tsconfig.json
to include the following settings
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Add a polyfill for the Reflect API (examples below use reflect-metadata). You can use:
The Reflect polyfill import should only be added once, and before DI is used:
// main.ts
import "reflect-metadata";
// Your code here...
class Foo { name = 'foo' }
class Bar { name = 'bar' }
// Use @moln/dependency-container demo
const container = new DependencyContainer();
container.registerSingleton(Foo);
container.registerSingleton('MyBar', Bar);
class BazComponent extends Component {
@inject() private foo!: Foo;
@inject('MyBar') private bar!: Bar;
render() {
return <div>hello {this.foo.name}! {this.bar.name}! </div>;
}
}