Skip to content

Instantly share code, notes, and snippets.

@andresgcarmona
Last active June 28, 2023 23:26
Show Gist options
  • Save andresgcarmona/cbbc8859357217d67de102d3cce4b01f to your computer and use it in GitHub Desktop.
Save andresgcarmona/cbbc8859357217d67de102d3cce4b01f to your computer and use it in GitHub Desktop.
Reduce React Context Hell
const App = () => {
return (
<MultiProvider
providers={[
<ReduxProvider value={store} />,
<ThemeProvider value={theme} />,
<OtherProvider value={otherValue} />,
<OtherOtherProvider value={otherOtherValue} />,
// ...others,
<HellProvider value={hell} />,
]}
>
<HelloWorld />
</MultiProvider>
)
}
import React from 'react'
const nest = (
children: React.ReactNode,
component: React.ReactElement
) => React.cloneElement(component, {}, children)
export type MultiProviderProps = React.PropsWithChildren<{
providers: React.ReactElement[]
}>
const MultiProvider: React.FC<MultiProviderProps> = ({
children,
providers
}) => (
<React.Fragment>
{providers.reduceRight(nest, children)}
</React.Fragment>
)
export default MultiProvider
import {Pipeline, Pipe} from 'react-pipeline-component'
<Pipeline components={[
<AppContextProvider children={<Pipe />} />,
<AnotherProvider children={<Pipe />} />,
<AgainAnotherProvider configProp={false} children={<Pipe />} />,
<TestProvider children={<Pipe />} />,
<FooProvider children={<Pipe />} />,
<BarProvider configHereAlso={someEnvronmentVar} children={<Pipe />} />,
<BazProvider children={<Pipe />} />,
<BatProvider children={<Pipe />} />,
<App />
]}/>
const Providers = ({providers, children}) => {
const renderProvider = (providers, children) => {
const [provider, ...restProviders] = providers;
if (provider) {
return React.cloneElement(
provider,
null,
renderProvider(restProviders, children)
)
}
return children;
}
return renderProvider(providers, children)
}
ReactDOM.render(
<Providers providers={[
<FooContext.Provider value="foo" />,
<BarContext.Provider value="bar" />,
<BazContext.Provider value="baz" />,
]}>
<App />
</Providers>,
document.getElementById('root')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment