Picture of the author
Jarred Kenny
Published on

React Provider Composition

Authors

One of the common challenges developers face when using the React Context API involves juggling with numerous Context Providers, sometimes leading to a "Provider Chaos", looking something like this:

const Primary = () => (
  <ProviderA>
    <ProviderB>
      <ProviderC>
        <ProviderD>
          <ProviderE>
            <App />
          </ProviderE>
        </ProviderD>
      </ProviderC>
    </ProviderB>
  </ProviderA>
)

While this structure isn't inherently flawed, as developers, we are always looking for innovative and more efficient methods to solve the same problem, in order to make our code more accessible and comprehensible to other developers. Through this continuous search, I discovered an improved approach to dealing with multiple Context Providers, enhancing my component's readability.

Embrace Composition In order to avert this kind of complex nesting, we can employ one of my favourite principles of the Functional Programming paradigm: Composition.

Rather than nesting one Provider within another, we can design a support function that amalgamates several Providers and yields a singular Provider component.

const composeProviders =
  (...providers) =>
  ({ children }) => {
    return providers.reduceRight(
      (decendents, Provider) => <Provider>{decendents}</Provider>,
      children
    )
  }

With our newly minted combineProviders function, we can merge our Providers as depicted below:

const Providers = composeProviders(ProviderA, ProviderB, ProviderC, ProviderD, ProviderE)

const Primary = () => (
  <Providers>
    <App />
  </Providers>
)