Skip to content

Omni Provider allows to merge multiple React Provider components into one

License

Notifications You must be signed in to change notification settings

morewings/react-omni-provider

Repository files navigation

Release types included npm version zero dependencies npm bundle size Maintainability Test Coverage

React Omni Provider

React Omni Provider

React Omni Provider is an utility component which allows to merge multiple Providers (wrapper components that create context or another global state).

Install

npm i react-omni-provider

Use

Provider component is a very popular React development pattern. Provider allows to create global state for your application. The problem is that today, plenty of libraries are using such approach. So after some time, your root file will probably look like the one below. Which sadly reminds infamous callback hell.

Before

import { ThemeProvider } from '@emotion/react'
import { Provider } from 'react-redux'
import { AuthProvider } from 'authorization-package';
import { ConsentProvider } from 'consent-package';
import { NotificationProvider } from '@/lib/Notification';
import { ModalProvider } from '@/lib/Modal';
import { FeatureProvider } from '@/lib/Feature';
// etc

export const App: FC<Props> = ({children}) => {
    return (
        <AuthProvider  secret={secret}>
            <ConsentProvider>
                <Provider store={store}>
                    <ThemeProvider theme={theme}>
                        <NotificationProvider>
                            <FeatureProvider>
                                <ModalProvider>
                                    {children}
                                </ModalProvider>
                            </FeatureProvider>
                        </NotificationProvider>
                    </ThemeProvider>
                </Provider>
            </ConsentProvider>
        </AuthProvider>
    );
};

After

React Omni Provider allows you to use just one Provider component instead. You can provide a list of used providers as an array. Providers are applied from left to right. So the first item in the list becomes the first wrapper.

import { OmniProvider } from 'react-omni-provider';
import { ProviderA } from 'ProviderA';
import { ProviderB } from 'ProviderB';
import { ProviderC } from 'ProviderC';

const providerConfig = [
        // you can add just provider component
        ProviderA,
        // or attach props to it
        [ProviderB, {prop: 'value'}],
        ProviderC
]

export const App: FC<Props> = ({children}) => {
    // same as <ProviderA><ProviderB prop="value"><ProviderC>{children}</ProviderC></ProviderB></ProviderA>
    return (
            <OmniProvider providerConfig={providerConfig}>
                {children}
            </OmniProvider>
    );
};

Higher-order Component

There is also a higher-order component available with the same functionality.

import type {ComponentProps} from 'react';
import { withOmniProvider } from 'react-omni-provider';
import { ProviderA } from 'ProviderA';
import { ProviderB } from 'ProviderB';
import { ProviderC } from 'ProviderC';

const providerConfig = [
        // you can add just provider component
        ProviderA,
        // or attach props to it
        [ProviderB, {prop: 'value'} as ComponentProps<typeof ProviderB>],
        ProviderC
]

const App: FC<Props> = ({children}) => {
    return (
            {children}
    );
};

export const WrappedApp = withOmniProvider(providerConfig)(App)