DEV Community

Cover image for No More React Context Hell
Denis Maushov
Denis Maushov

Posted on

No More React Context Hell

If you always wanted it to look like this

  <Providers providers={[
    <FooContext.Provider value="foo" />,
    <BarContext.Provider value="bar" />,
    <BazContext.Provider value="baz" />,
  ]}>
    <App />
  </Providers>,
Enter fullscreen mode Exit fullscreen mode

here is your Providers Component:

const Providers = ({providers, children}) => {
  const renderProvider = (providers, children) => {
    const [provider, ...restProviders] = providers;

    if (provider) {
      return React.cloneElement(
        provider,
        null,
        renderProvider(restProviders, children)
      )
    }

    return children;
  }

  return renderProvider(providers, children)
}
Enter fullscreen mode Exit fullscreen mode

Enjoy!

Like, share and etc

Top comments (2)

Collapse
 
dsaga profile image
Dusan Petkovic •

Any chance to show an example with typescript?

Collapse
 
schoon profile image
Dan Schoonmaker •
import { cloneElement } from "react";

type Props = {
  providers: Array<React.ReactElement>;
  children: React.ReactNode;
};

const Providers = ({ providers, children }: Props) => {
  const renderProvider = (
    providers: Array<React.ReactElement>,
    children: React.ReactNode,
  ): JSX.Element | React.ReactNode => {
    const [provider, ...restProviders] = providers;

    if (provider) {
      return cloneElement(
        provider,
        undefined,
        renderProvider(restProviders, children),
      );
    }

    return children;
  };

  return <>{renderProvider(providers, children)}</>;
};

export default Providers;
Enter fullscreen mode Exit fullscreen mode