Provider Pattern with React Context API

Provider Pattern with React Context API

Provider Pattern with React Context API 1228 702 Gobinda Thakur

React’s provider pattern is a powerful concept. React uses provider pattern in Context API to share data across the tree descendant nodes. You may not find this useful when you are using plain react. However, this pattern comes handy when you are designing a complex app since it solves multiple problems.

What is React’s context API?

According to React docs, “Context provides a way to pass data through the component tree without having to pass props down manually at every level.”

This means Context API helps us to skip the mandatory hierarchy of passing props for each component in its component tree.

Provider pattern and Context API

Provider pattern, however, is not only about react context. You might have used a state management library like redux and mobX. Here provider is the top most component and it is provided by react-redux. We write it the following way:

In fact, react-redux has implemented the provider pattern where Provider component receives the state as props, and post that, each child component has implicit access to the managed state.

Let’s now look at what problem(s) provider pattern can solve in react.

You might have heard about props-drilling. While building your application, you may be at a stage where you are drilling through many layers of components.

Props Drilling

Props Drilling

For example, in the image above, we have component <A/>. Here we have a prop called “name”. We need this to use in component <I/>. For this, we need to send the same props to several layers. If the components <C/> and <G/> don’t need the prop “name” then we shouldn’t expose this data to them. We need to have something so that <I/> can access the data directly without revealing it to all other components.

To solve this problem, we would need a global object to which components can have direct access in the react tree. React’s context API has implemented the provider pattern exactly for this use case. The provider consumer relation is very handy in this context. Provider can provide the data/ API which can be consumed by the consumers.

Context API is not the only solution to the above problem. Please go through this link to see how well thought out design can solve such problems.

Where can you use Context API?

Some sample use cases where the Context API proves helpful are:

  • Theming — Pass down app theme
  • i18n — Pass down translation messages
  • Authentication — Pass down current authenticated user

Let’s now dig into a real-world example applying all that we learnt about the provider pattern and context API.

1. Explaining the different parts of the application

In this example, we intend to change the theme and perform translation basis the selected language.

We have the following components:

  1. <LanguageSelection/> – Has a label “Select Language” and a drop down which has a list of languages.
  2. <ThemeContainer/> – Has a label “Change Theme”, theme type and a toggle button.
  3. <Content/> – Simply shows the content “Hello world!!”.

We have three languages – English, French and Spanish. The text on the screen should change to the respective language basis your selection.

There are two themes, light and dark – you can toggle it using the button. It will also show the selected theme.

2. Document Tree

We can imagine the tree like this:

Document Tree

Parent component is nothing but the provider which has language and theme in the state. It also has APIs(methods) to change the language and theme. Given this, all child components can consume the data and API directly.

3. <AppProvider/>

As you can see, in this component, we are exposing the states, “updateLocale” and “updateTheme”. In the states, we have all the data which is shown in the UI whereas “updateLocale” and “updateTheme” are the callbacks which are going to be used by the consumers. Here “updateLocale” holds the definition of updateLocaleCode method – its job is to change the language. “updateTheme” holds the definition of the method “updateTheme” which toggles the theme to light or dark.

4. Let’s quickly check the render of all the three components

A. LanguageSelection


We are using render props and accessing the data using {context.state.localObj.languageLabel}. Also, on changing the selection, we invoke the callback using {context.updateLocale}.

For an in-depth introduction, you can refer my blog on render props.

B. ThemeContainer

C. Content


We access the data in ThemeContainer and Content while we invoke the callback {context.updateTheme} basis the toggle button in ThemeContainer.


Conclusion

We looked at how useful the provider pattern can be in creating a clean design. This is extremely helpful when building a complex application with multiple components. It also helps you write robust code while ensuring security.

That’s all for now on the provider pattern. Watch out this space for more articles on React Patterns!

P.S: In case you missed reading our in-depth introduction to Render Props, you can find it here.

Gobinda Thakur

Fullstack web developer

2 Comments
  • Gobinda thanks for a good and crisp understanding of Provider pattern and now Context API implements it… A very nice read..

    • Thank you Siddharth Kar. Please share it with your friends and colleagues. It will help them in understanding the concept.