useDependency
React hook that resolves some component (not UI component) from DI container, provided by special context.
You can read more about DI container here: DI overview
Usage
import { useEffect } from 'react';
import { useDependency } from '@krutoo/utils/react';
import { TOKEN } from '#app/token';
function App() {
const logger = useDependency(TOKEN.logger);
useEffect(() => {
logger.info('App mounted');
}, []);
return (
<main>
<h1>My app</h1>
{/* ... */}
</main>
);
}
Provider of DI-container
Hook useDependency will throw error if component is not wrapped by ContainerContext by design.
You can make this in your app' entrypoint:
import { createRoot } from 'react-dom/client';
import { createContainer } from '@krutoo/utils/di';
import { ContainerProvider } from '@krutoo/utils/react';
import { App } from '#components/app';
const container = createContainer();
// ...fill your container
createRoot(document.querySelector('#root')).render(
<ContainerProvider container={container}>
<App />
</ContainerProvider>,
);
Custom context
There are situations where some internal part of an application is encapsulated and needs to use the context of a DI container.
In this case, using the context within the application itself will not allow for separation of dependencies between the application itself and its internal subsystem.
A custom context can be used for this separation. The context prop and createDependencyHook function can help with this.
import { createContext } from 'react';
import { createDependencyHook } from '@krutoo/utils/react';
const SubAppContainerContext = createContext(null);
const useSubAppDependency = createDependencyHook(SubAppContainerContext);
// ...later you can use it
const subAppContainer = createContainer();
function SubApp() {
const logger = useSubAppDependency(TOKEN.logger);
return <>{/* ... */}</>;
}
<ContainerProvider container={subAppContainer} context={SubAppContainerContext}>
<SubApp />
</ContainerProvider>;