DEV Community

Horus Lugo
Horus Lugo

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

27 7

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

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

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

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post