Skip to content

kolodny/react-compose-wrappers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-compose-wrappers

NPM version Build status Downloads

This package solves the issue of many providers forcing indentation runoffs.

Problem

Here's how a simple component can evolve to:

const MyApp: React.FunctionComponent = () => {
  const foo: Foo = { /* ... */ };
  const bar: Bar = { /* ... */ };
  const baz: Baz = { /* ... */ };
  return (
    <FooContext.Provider value={foo}>
      <BarContext.Provider value={bar}>
        <BazContext.Provider value={foo}>
          <MainComponent />
        </BazContext.Provider>
      </BarContext.Provider>
    </FooContext.Provider>
  );
}

Now when the user adds a ApolloProvider and react-intl, we need to keep wrapping our components.

const MyApp: React.FunctionComponent = () => {
  const locale = getLocale()
  const messages = getMessages(locale);
  const client = getApolloClient();
  const foo: Foo = { /* ... */ };
  const bar: Bar = { /* ... */ };
  const baz: Baz = { /* ... */ };
  return (
    <IntlProvider locale={locale} messages={messages}>
      <ApolloProvider client={client}>
        <FooContext.Provider value={foo}>
          <BarContext.Provider value={bar}>
            <BazContext.Provider value={foo}>
              <MainComponent />
            </BazContext.Provider>
          </BarContext.Provider>
        </FooContext.Provider>
      </ApolloProvider>
    </IntlProvider>
  );
}

Solution

This makes our component noisy and needlessly nested. This library fixes that by allowing you to specify the wrapping strategy without needing to indent or alter the rendering code:

import { composeWrappers } from 'react-compose-wrappers';

const MyApp: React.FunctionComponent = () => {
  const locale = getLocale()
  const messages = getMessages(locale);
  const client = getApolloClient();
  const foo: Foo = { /* ... */ };
  const bar: Bar = { /* ... */ };
  const baz: Baz = { /* ... */ };

  const SuperProvider = composeWrappers([

                           // Note: children can be passed via children={props.children}
    props => <IntlProvider locale={locale} messages={messages} children={props.children} />,

         // Or the usual way of <MyComponent>{props.children}</MyComponent>
    props => <ApolloProvider client={client}>{props.children}</ApolloProvider>,

    props => <FooContext.Provider value={foo}>{props.children}</FooContext.Provider>,
    props => <BarContext.Provider value={bar}>{props.children}</BarContext.Provider>,
    props => <BazContext.Provider value={baz}>{props.children}</BazContext.Provider>,
  ]);

  return (
    <SuperProvider>
      <MainComponent />
    </SuperProvider>
  );
}

Now when a new wrapper or provider is needed, you only need to alter that array with how the component should be wrapped.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published