cheap-di-react
Integration of cheap-di into React via React.Context
Installation
npm i cheap-di-react
How to use
There is a simple logger.
export abstract class Logger {
abstract debug(message: string): void;
}
export class SimpleConsoleLogger extends Logger {
debug(message: string) {
console.log(message);
}
}
export class ConsoleLoggerWithPrefixes extends Logger {
constructor(private prefix: string) {
super();
}
debug(message: string) {
console.log(`${this.prefix}: ${message}`);
}
}
Use it in the React component
import { DIProvider } from 'cheap-di-react';
import { Logger, SimpleConsoleLogger, ConsoleLoggerWithPrefixes } from './logger';
import { ComponentA } from './ComponentA';
const App = () => {
return (
<DIProvider
// will update dependencies on each render
dependencies={[
dr => dr.registerImplementation(ConsoleLoggerWithPrefixes).as(Logger).inject('my message'),
]}
// will update dependencies on each render
self={[SimpleConsoleLogger]}
>
<ComponentA/>
</DIProvider>
);
};
import {
use,
useDi,
} from 'cheap-di-react';
import { Logger, SimpleConsoleLogger } from './logger';
const ComponentA = () => {
const logger = use(Logger);
logger.debug('foo');
const simpleLogger = use(SimpleConsoleLogger);
simpleLogger.debug('bar');
return <>...</>;
};
Optimizations
You should memoized dependencies registration to avoid extra re-renders of entire tree
import {
DIProvider,
use,
Dependency,
SelfDependency,
} from 'cheap-di-react';
import { ComponentA } from './ComponentA';
abstract class Foo {}
class FooImpl extends Foo {}
class Bar {}
const App = () => {
const dependencies = useMemo<Dependency[]>(() => [
dr => dr.registerImplementation(Foo).as(FooImpl),
], []);
const selfDependencies = useMemo<SelfDependency[]>(() => [Bar], []);
return (
<DIProvider
dependencies={dependencies}
self={selfDependencies}
>
<ComponentA/>
</DIProvider>
);
};
Or you may use DIProviderMemo to minimize code above
import { DIProviderMemo, use } from 'cheap-di-react';
import { ComponentA } from './ComponentA';
abstract class Foo {}
class FooImpl extends Foo {}
class Bar {}
const App = () => {
const dependencies = useMemo<Dependency[]>(() => [
dr => dr.registerImplementation(Foo).as(FooImpl),
], []);
const selfDependencies = useMemo<SelfDependency[]>(() => [Bar], []);
return (
<DIProviderMemo
dependencies={[
dr => dr.registerImplementation(Foo).as(FooImpl),
]}
self={[Bar]}
>
<ComponentA/>
</DIProviderMemo>
);
};