4.1.2 • Published 3 months ago

cheap-di-react v4.1.2

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

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.

// logger.ts
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

// App.tsx
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>
  );
};

// ComponentA.tsx
import {
  use,
  // if you have concerns about `use` name you can use `useDi` instead of 
  useDi, // alias for `use` hook
} from 'cheap-di-react';
import { Logger, SimpleConsoleLogger } from './logger';

const ComponentA = () => {
  const logger = use(Logger); // will get ConsoleLoggerWithPrefixes instance here
  logger.debug('foo'); // "my message: foo"
  
  const simpleLogger = use(SimpleConsoleLogger); // will get SimpleConsoleLogger instance here, because it is registered as itself
  simpleLogger.debug('bar'); // "bar"

  return <>...</>;
};

Optimizations

You should memoized dependencies registration to avoid extra re-renders of entire tree

// App.tsx
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

// App.tsx
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>
  );
};
4.1.2

3 months ago

4.1.1

5 months ago

4.1.0

5 months ago

4.1.0-rc-31

5 months ago

4.1.0-rc-32

5 months ago

4.1.0-rc-30

5 months ago

4.1.0-rc-10

5 months ago

4.1.0-rc-11

5 months ago

4.1.0-rc-12

5 months ago

4.1.0-rc-9

5 months ago

4.1.0-rc-8

5 months ago

4.1.0-rc-6

5 months ago

4.1.0-rc-7

5 months ago

4.1.0-rc-4

5 months ago

4.1.0-rc-5

5 months ago

4.1.0-rc-1

6 months ago

4.1.0-rc-2

5 months ago

4.1.0-rc-3

5 months ago

4.0.3

10 months ago

4.0.1

2 years ago

4.0.0

2 years ago

4.0.2

2 years ago

3.3.1

2 years ago

3.3.0

2 years ago

3.2.2

2 years ago

3.2.3

2 years ago

3.2.1

3 years ago

3.0.0

3 years ago

1.1.1

3 years ago

1.0.2

3 years ago

1.1.0

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago