Skip to content

Instantly share code, notes, and snippets.

@yeasin2002
Last active June 21, 2025 16:16
Show Gist options
  • Save yeasin2002/35d3274c68652095a35cd8189a412351 to your computer and use it in GitHub Desktop.
Save yeasin2002/35d3274c68652095a35cd8189a412351 to your computer and use it in GitHub Desktop.
No More React Context Hell

The Problem

export function App() {
  return (
    <CountProvider>
      <AuthProvider>
        <ThemeProvider>
          <CacheProvider>
            <IntlProvider>
              <TooltipProvider>
                <UserSettingsProvider>
                  <NotificationProvider>
                    <AnalyticsProvider>
                      <Content />
                    </UserSettingsProvider>
                  </NotificationProvider>
                </AnalyticsProvider>
              </TooltipProvider>
            </IntlProvider>
          </CacheProvider>
        </ThemeProvider>
      </AuthProvider>
    </CountProvider>
  );
}

Create the provider

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

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)
}

another way:

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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment