jesseflorig.dev

Provider Hell

February 28, 2020☕️2 min read

If you’re familiar with React Context Providers, you know how quickly your App.js can turn into something like this:

const App = () => (
  <ThemeProvider>
    <CSSReset />
    <ColorModeProvider>
      <SocketIOProvider>
        <UserProvider>
          <SomeOtherDataProvider>
            <Routes />
          </SomeOtherDataProvider>
        </UserProvider>
      </SocketIOProvider>
    </ColorModeProvider>
  </ThemeProvider>
)

It’s really not that bad, but when it comes to adding new providers to your App.js, it’s not always clear where it should go in the tree. Looking at the example above, you might have noticed there are two main types of providers being used: style and data providers. If you didn’t notice, then you understand why it might be difficult for other devs to know where to add new providers.

We can easily fix this by creating a couple provider components that group similar concerns together.

Higher Order Providers

Let’s create a <StyleProvider /> and <DataProvider /> that contains their respective providers. Since we’ll use both to wrap the content of our app, we’ll desctructure children from props.

Style Provider

First lets put all the style related providers into a component:

const StyleProvider = ({ children }) => (
  <ThemeProvider>
    <CSSReset />
    <ColorModeProvider>
      {children}
    </ColorModeProvider>
  </ThemeProvider>
)

Data Provider

Then we can do the same for our data related providers:

const StyleProvider = ({ children }) => (
  <SocketProvider>
    <UserProvider>
      <SomeOtherDataProvider>
        {children}
      </SomeOtherDataProvider>
    </UserProvider>
  </SocketProvider>
)

Putting it back together

With our grouped providers created, we can use them to clean up our <App /> component:

const App = () => (
  <StyleProvider>
    <DataProvider>
      <Routes />
    </DataProvider>
  </StyleProvider>
)

Now its very clear that if we ever need to add style or data providers, we can add them to their respective higher order provider. And should we ever have a provider not fall into either of those buckets, we can add them directly to the <App/> component or create a new higher order component.


Written by Jesse Florig.
Powered by coffee.