DEV Community

Horus Lugo
Horus Lugo

Posted on • Edited on • Originally published at horus.dev

Say Goodbye To Provider Hell With react-component-pack

If you're developing apps with React, you may have faced something like this:

function App() { return ( <AuthProvider> <DataProvider> <AnotherDataProvider> <WtfProvider> <ThisIsGettingReallyBigProvider> <OhMyGodTheresMoreProvider> <FinallySomeRealComponents /> </OhMyGodTheresMoreProvider> </ThisIsGettingReallyBigProvider> </WtfProvider> </AnotherDataProvider> </DataProvider> </AuthProvider> ); } 
Enter fullscreen mode Exit fullscreen mode

That's what people call Provider Hell and I created this tool to make this kind of code more readable.

Here's the same example, using the react-component-pack utility:

import { createPack } from 'react-component-pack'; const ProviderPack = createPack( AuthProvider, DataProvider, AnotherDataProvider, WtfProvider, ThisIsGettingReallyBigProvider, OhMyGodTheresMoreProvider ); function App() { return ( <ProviderPack> <FinallySomeRealComponents /> </ProviderPack> ); } 
Enter fullscreen mode Exit fullscreen mode

NOTE: This utility won't allow you to pass props to a specific provider. Feel free to submit a PR 😁

GitHub logo HorusGoul / react-component-pack

Library that allows you to create context provider groups

React Component Pack · npm version license

Say goodbye to provider hell with react-component-pack, a utility that allows you to group multiple components into a single one

npm install react-component-pack
Enter fullscreen mode Exit fullscreen mode

Usage

With react-component-pack you can go from this:

function App() { return ( <AuthProvider> <DataProvider> <AnotherDataProvider> <WtfProvider> <ThisIsGettingReallyBigProvider> <OhMyGodTheresMoreProvider> <FinallySomeRealComponents /> </OhMyGodTheresMoreProvider> </ThisIsGettingReallyBigProvider> </WtfProvider> </AnotherDataProvider> </DataProvider> </AuthProvider> ); }
Enter fullscreen mode Exit fullscreen mode

To this:

import { createPack } from 'react-component-pack'; const ProviderPack = createPack( AuthProvider, DataProvider, AnotherDataProvider, WtfProvider, ThisIsGettingReallyBigProvider, OhMyGodTheresMoreProvider ); function App() { return ( <ProviderPack> <FinallySomeRealComponents /> </ProviderPack> ); }
Enter fullscreen mode Exit fullscreen mode

Top comments (5)

Collapse
 
1987cr profile image
Carlos Riera

I wouldn't install a new dependency on my project to do this when you can achieve (probably) the same result just writing a small function like this one:

const nest = (...components) => props => components.reduce((children, Current) => <Current {...props}>{children}</Current>, props.children);  const ProviderPack = nest( AuthProvider, DataProvider, AnotherDataProvider, WtfProvider, ThisIsGettingReallyBigProvider, OhMyGodTheresMoreProvider ); 
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mxmzb profile image
Maxim

How do you handle Providers which require props, e.g. Draqula requires a client (and so does Apollo and many others)? Am I supposed to do something like

const ProviderPack = createPack( AuthProvider, DataProvider, AnotherDataProvider, WtfProvider, ThisIsGettingReallyBigProvider, OhMyGodTheresMoreProvider, () => DraqulaProvider({ client: myClient }) ); 
Enter fullscreen mode Exit fullscreen mode

? Not that it's too bad, now that I look at it :D

Collapse
 
horusgoul profile image
Horus Lugo

Almost there, remember that invoking components like that is not recommended, just change it to use JSX:

() => <DraqulaProvider client={myClient} /> 
Enter fullscreen mode Exit fullscreen mode
Collapse
 
aknaiotto profile image
aknaiotto

You can create a wrapper component using the children prop containing all providers and having as props all the things you need to pass to providers.

Collapse
 
seanmclem profile image
Seanmclem • Edited

I like this! I was looking for something just like it recently. I'll definitely be using this