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