DEV Community

Horus Lugo
Horus Lugo

Posted on • Updated 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