Search code examples
reactjsreact-context

Too many React Context providers


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?


Solution

  • 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<unknown>>>
        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.