Created
March 5, 2024 04:57
-
-
Save joemaffei/0e31a9480da630efc9030c857905a165 to your computer and use it in GitHub Desktop.
Simple dependency injection in React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const $dependencyContext = Symbol(); | |
/** | |
* The provide function would be called at the root of the application, | |
* or at the "root" of a dynamically imported module. | |
*/ | |
function provide<T extends Record<symbol, any>>(deps: T) { | |
(globalThis as any)[$dependencyContext] = { | |
...(globalThis as any)[$dependencyContext], | |
...deps, | |
}; | |
} | |
/** | |
* Simple accessor for the global dependency context. | |
*/ | |
function inject() { | |
return (globalThis as any)[$dependencyContext]; | |
} | |
/** Unique identifier for some dependency. */ | |
const $someDep = Symbol(); | |
/** | |
* This is decoupled from a specific dependency/import. | |
*/ | |
const Component = () => { | |
const { [$someDep]: dep } = inject(); | |
return <div>{dep()}</div>; | |
}; | |
/** | |
* This implementation provides Component one version of the dependency. | |
* In practice, `provide` would not be called multiple times within an | |
* application for the same dependencies. Imagine this is the "production" | |
* version of the global App. | |
*/ | |
const Component1 = () => { | |
provide({ [$someDep]: () => 'someDep' }); | |
return <Component />; | |
}; | |
/** | |
* This implementation provides another version of the dependency. | |
* Imagine this is the "test" version of the global App. | |
*/ | |
const Component2 = () => { | |
provide({ [$someDep]: () => 'someInjectedDep' }); | |
return <Component />; | |
}; | |
function App() { | |
return ( | |
<> | |
<Component1 /> | |
<Component2 /> | |
<Component1 /> | |
<Component2 /> | |
</> | |
); | |
} | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://stackblitz.com/edit/vitejs-vite-u4smdc?file=src%2FApp.tsx