Compose React Providers

This is a simple example of a TypeScript React function that can assist in combining many Provider components, such as those used by React Context, into a straightforward function.

import React, { Fragment } from 'react';

function compose(...components: React.FC[]): React.FC {
  return (
    components.reduce(
      (Accumulator, Component) =>
        ({ children }: React.ComponentProps<FC>): JSX.Element =>
          (
            <Accumulator>
              <Component>{children}</Component>
            </Accumulator>
          )
    ),
    (props) => <Fragment {...props} />
  );
}

With this, you can now simply compose your providers like so:

import React from 'react';
import { compose } from '@util';

const App = () => {
  const Provider = compose(
    uiContext.Provider,
    authContext.Provider,
    exampleContext.Provider,
    reallyLongExampleContext.Provider,
  );

  return (
    <Provider>
      </App>
    </Provider>
  );
}

Which is much much better than:

import React from 'react';

const App = () => {
  const Provider = compose(
    uiContext.Provider,
    authContext.Provider,
    exampleContext.Provider,
    reallyLongExampleContext.Provider,
  );

  return (
    <uiContext.Provider>
      <authContext.Provider>
        <exampleContext.Provider>
          <reallyLongExampleContext.Provider>
            </App>
          </reallyLongExampleContext.Provider>
        </exampleContext.Provider>
      </authContext.Provider>
    </uiContext.Provider>
  );
}