DEV Community

loading...

Provider Pattern

fosteman profile image Timothy Fosteman Updated on ・2 min read

Provider Pattern

React functionalities context and children enable to implement provider pattern. Essentially making properties accessible in the context of supplying component.

ContextAPI

It is a powerful feature removing clutter of drilling, for example, theme properties, down the component tree to each component. Mandatory properties are emplaced with childContextTypes object, describing component's requirements.

In A component you provide the context. It is a hardcoded colored theme property in this case, but it can be anything from component state to component props. Component A display component D but makes the context available to all its children. In component C, somewhere below component D, you could consume the context object. Notice that component A doesn’t need to pass down anything via component D in the props.

class A extends React.Component { 
    getChildContext() {
      return {
        coloredTheme: "green"
      }; 
    }
    render() { 
      return <D />;
    } 
}
A.childContextTypes = {
      coloredTheme: PropTypes.string
};
class C extends React.Component { 
        render() {
          return (
            <div style={{ color: this.context.coloredTheme }}>
                  {this.children} 
            </div>
        ); 
        }
}
C.contextTypes = {
      coloredTheme: PropTypes.string
};

By using the colored theme property from this.context, the component can derive its style. That way every component that needs to be styled according to the colored theme could get the necessary information from React’s context object.

Provider component would implement like this:

class ThemeProvider extends React.Component { 
    getChildContext() {
      return {
             coloredTheme: this.props.coloredTheme
             }; 
    }
    render() {
      return <div>{this.props.children}</div>;
    } 
}
ThemeProvider.childContextTypes = {
      coloredTheme: PropTypes.string
};

The Provider component only sets the colored theme from the incoming props. In addition, it renders its children.

After declaring the Provider component, you can use it anywhere in your React component tree. But it makes most sense to use it at the top of your component hierarchy to make the context, the colored theme, accessible to everyone.

const coloredTheme = "green";
    // hardcoded theme
    // however, imagine the configuration is located somewhere else // and would be different for every user of your application // it would need to be fetched first
    // and varies depending on the app user
ReactDOM.render(
      <ThemeProvider coloredTheme={coloredTheme}>
        <App />
      </ThemeProvider>,
      document.getElementById('app')
);

Now, every child component can consume the colored theme provided by the ThemeProvider component. It doesn’t need to be the direct child, in this case the App component, but any component down the component tree.

class App extends React.Component {
  render() {
    return ( 
    <div>
      <Paragraph>
      That 's how you would use children in React 
      </Paragraph> 
    </div>
    );
  }
}
class Paragraph extends React.Component {
    render() {
      const {coloredTheme} = this.context;
      return ( 
        <p style={{color: coloredTheme}}> 
          {this.props.children} 
        </p> 
        );
      }
    }
Paragraph.contextTypes = {
      coloredTheme: PropTypes.string
};

That’s basically it for the provider pattern. You have the Provider component that makes properties accessible in React’s context and components that consume the context.

Discussion

pic
Editor guide