ditox-react
Version:
Dependency injection container for React.js
73 lines • 2.39 kB
JavaScript
import { createContainer } from 'ditox';
import React, { createContext, useContext, useEffect, useMemo, } from 'react';
export const DependencyContainerContext = createContext(undefined);
/**
* Provides a new dependency container to React app
*
* This component creates a new container and provides it down to React children.
*
* If `binder` callback is specified, it will be called for a new container
* to binds it with dependencies.
*
* If a parent container is exist, it is connected to the current one by default.
* For making a new root container specify `root` parameter as `true`,
* and the container will not depend on any parent container.
*
* @param params.binder - A callback which setup bindings to the container.
* @param params.root - If `true` then a new container does not depend on any parent containers
*
* @example
*
* ```tsx
* const TOKEN = token();
*
* function appDependencyBinder(container: Container) {
* container.bindValue(TOKEN, 'value');
* }
*
* function App() {
* return (
* <DependencyContainer root binder={appDependencyBinder}>
* <NestedComponent />
* </DependencyContainer>
* );
* }
* ```
*
*/
export function DependencyContainer(params) {
const { children, root, binder } = params;
const parentContainer = useContext(DependencyContainerContext);
const container = useMemo(() => {
const container = createContainer(root ? undefined : parentContainer);
binder === null || binder === void 0 ? void 0 : binder(container);
return container;
}, [binder, parentContainer, root]);
useEffect(() => {
return () => container.removeAll();
}, [container]);
return (React.createElement(DependencyContainerContext.Provider, { value: container }, children));
}
/**
* Provides a custom dependency container to React app
*
* @param params.container - a custom container
*
* @example
* ```tsx
* const container = useMemo(() => {
* return createContainer();
* }
*
* return (
* <CustomDependencyContainer container={container}>
* {children}
* </CustomDependencyContainer>
* );
* ```
*/
export function CustomDependencyContainer(params) {
const { children, container } = params;
return (React.createElement(DependencyContainerContext.Provider, { value: container }, children));
}
//# sourceMappingURL=DependencyContainer.js.map