ditox-react
v3.3.0
Published
Dependency injection for web applications: adapters for React.js
Downloads
460
Maintainers
Readme
ditox-react package
Dependency injection helpers for React.js
Please see the documentation at ditox.js.org
Installation
You can use the following command to install this package:
npm install --save ditox-reactPackages can be used as UMD modules. Use jsdelivr.com CDN to load ditox and ditox-react:
<script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js"></script>
<script src="//cdn.jsdelivr.net/npm/ditox-react/dist/umd/index.js"></script>
<script>
const container = Ditox.createContainer();
// DitoxReact.useDependency(SOME_TOKEN);
</script>Overview
ditox-react is a set of helpers for providing and using a dependency container
in React apps:
- Components:
DependencyContainer— creates and provides a new container to React children. Optionally binds dependencies via a binder callback. Can start a new root container withrootflag.DependencyModule— binds a dependency module to a new container (supportsscope:singleton(default) orscoped).CustomDependencyContainer— provides an existing dependency container.
- Hooks:
useDependencyContainer(mode?)— returns a provided dependency container. Withmode = 'strict'it throws if the container is not provided; by default it returnsundefinedwhen not provided.useDependency(token)— resolves and returns a value by a specified token. Throws if a container or the value is not found.useOptionalDependency(token)— returns a resolved value by a specified token, orundefinedif not found or not provided.
Usage Examples
import {token} from 'ditox';
import {
DependencyContainer,
useDependency,
useDependencyContainer,
useOptionalDependency,
} from 'ditox-react';
const FOO_TOKEN = token<string>();
const BAR_TOKEN = token<string>();
function appDependencyBinder(container) {
container.bindValue(FOO_TOKEN, 'foo');
}
function App() {
return (
<DependencyContainer root binder={appDependencyBinder}>
<NestedComponent />
</DependencyContainer>
);
}
function NestedComponent() {
// Get access to the container (optionally)
const container = useDependencyContainer(); // or useDependencyContainer('strict') to enforce presence
// Use a resolved value
const foo = useDependency(FOO_TOKEN);
// Use an optional value. It is not provided in this example.
const bar = useOptionalDependency(BAR_TOKEN);
useEffect(() => {
console.log({foo, bar}); // {foo: 'foo', bar: undefined}
}, [foo, bar]);
return null;
}Providing an existing container
import {createContainer, token} from 'ditox';
import {CustomDependencyContainer, useDependency} from 'ditox-react';
const GREETING_TOKEN = token<string>();
const container = createContainer();
container.bindValue(GREETING_TOKEN, 'Hello');
function App() {
return (
<CustomDependencyContainer container={container}>
<Greeting />
</CustomDependencyContainer>
);
}
function Greeting() {
const text = useDependency(GREETING_TOKEN);
return <>{text}</>;
}Dependency Modules
Dependency modules can be provided to the app with the <DependencyModule />
component. You can also specify a binding scope (singleton by default or
scoped):
function App() {
return (
<DependencyModule module={LOGGER_MODULE} scope="singleton">
<NestedComponent />
</DependencyModule>
);
}API Reference
Components
- DependencyContainer(props)
- props.children: ReactNode — React children to wrap
- props.root?: boolean — if true, create a new root container that does not inherit from any parent container
- props.binder?: (container: Container) => unknown — optional callback to set up bindings for the newly created container
- Behavior: creates a new container linked to the parent container by default; removes all bindings on unmount
- CustomDependencyContainer(props)
- props.children: ReactNode — React children to wrap
- props.container: Container — an existing container instance to provide
- DependencyModule(props)
- props.children: ReactNode — React children to wrap
- props.module: ModuleDeclaration — module to bind to a new container
- props.scope?: 'singleton' | 'scoped' — scope for the module bindings (default: 'singleton')
- DependencyContainer(props)
Hooks
- useDependencyContainer(mode?: 'optional' | 'strict')
- Returns the container. In 'strict' mode throws if not provided; in optional mode returns undefined if not provided
- useDependency(token: Token): T
- Resolves and returns the value; throws if not bound or container is missing
- useOptionalDependency(token: Token): T | undefined
- Returns the value if bound, otherwise undefined
- useDependencyContainer(mode?: 'optional' | 'strict')
Notes:
- A parent container (if provided higher in the tree) is used as the parent for new containers created by DependencyContainer and DependencyModule, unless root is set to true.
- All bindings made inside a DependencyContainer are removed on unmount.
This project is licensed under the MIT license.
