New to react here and trying to wrap my head round the new Context API (I haven't looked into Redux etc. yet).
Seems I can do much of what I need to do, but I'm going to end up with lots and lots of providers, all needing a tag to wrap my main app.
I'm going to have a provider for Auth, one for theming, one for chat messages (vis Pusher.com) etc. Also using React Router is another wrapper element.
Am I going to have to end up with this (and many more)....
<BrowserRouter> <AuthProvider> <ThemeProvider> <ChatProvider> <App /> </ChatProvider> </ThemeProvider> </AuthProvider> </BrowserRouter>
Or is there a better way?
If you want a solution for composing Providers without any third-party libraries, here's one with Typescript annotations:
// Compose.tsx interface Props { components: Array<React.JSXElementConstructor<React.PropsWithChildren<any>>> children: React.ReactNode } export default function Compose(props: Props) { const { components = [], children } = props return ( <> {components.reduceRight((acc, Comp) => { return <Comp>{acc}</Comp> }, children)} </> ) }
Usage:
<Compose components={[BrowserRouter, AuthProvider, ThemeProvider, ChatProvider]}> <App /> </Compose>
You can of course remove the annotations if you don't use Typescript.
Solution with for
loop:
export const provider = (provider, props = {}) => [provider, props]; export const ProviderComposer = ({providers, children}) => { for (let i = providers.length - 1; i >= 0; --i) { const [Provider, props] = providers[i]; children = <Provider {...props}>{children}</Provider> } return children; }
Usage:
<ProviderComposer providers={[ provider(AuthProvider), provider(ThemeProvider), provider(MuiPickersUtilsProvider, {utils: DateFnsUtils}), ]} > <App/> </ProviderComposer>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With