Hey everyone! ❤️

This time I’m going to show how to use the Context API in React.

Context provides a way to pass data through the component tree without having to pass props down manually along every level.

React typically works with a top-down (parent to child) flow of data. This works very well in a cascade of props, always giving the virtual DOM ability to check it and trigger re-renderings when they’re needed.

We also have local state inside each stateful component to manage changes allowing the user to change data that is propagated via props.

When we want to abstract a little bit more, we can use Redux to abstract state or props to an “external” store, a single source of truth — if you haven’t read my article about How to get the ball rolling with Redux in ten minutes, feel free to do it!

Even with all these tools in the tool belt it can be cumbersome to handle some type of data (props, state, whatever) inside our application.

Imagine current authenticated user info, themes, locale️ or even language related data.

This is information that is considered to be “global” in a tree of React components. Once you change this info, all the application should re-render to get up-to-date with it.

Context is designed to share data that can be considered “global”.

So, to understand this, let’s get our hands dirty! If you want you can pull my GitHub repo here and play a bit with these things we’re going to do:

01. Getting Our Hands Dirty

Let’s build an App, which has a Dashboard.

Inside the Dashboard there’s a Widget which renders a Themed Button.

The Themed Button allows the user to change the App Theme.

Something like this:

6MtkhVhYrMlECQeAxuheRqIg3KoaxjSdyXXn
Image of the App

So, let’s start with our App component:

2EqqvPMMI15R9OCIkgOlUl8sdQvtGJ4TGcVr
App Component

This component has a state, a changeTheme method and a render which renders the <Dashboard /> Component.

oSyRro0zLaTZDxeupfrGsEbvDC0sQnWJkNFH
Dashboard Component

Dashboard Component receives props and renders a Widget Component passing the changeTheme and theme props.

4c8zM8aEJ-X8Z97TM5KZV5r1pITAAPfeebQr
Widget Component

Widget Component receives props from its parent and renders a Button passing into it changeTheme and theme props.

DiKuckapUyedtersEvx4XKMlCy114dILkFXP
Button Component

The Button receives the props from its parent and finally makes use of it rendering a button with a className that depends on the theme that was chosen by the user.

The Button also allows the user to switch the theme from red to blue and vice-versa. That’s why it has an onClick handler which triggers the changeTheme method passed top down from App Component -> Dashboard -> Widget -> Button.

As you see everyone, this is a lot of props, a lot of complexity, a lot of repeated code, a lot of ?.

So, at this moment, you’re asking how can we avoid this? How can we abstract all these theme things and make our code cleaner?

The answer for this is making use of the Context API provided by React!!

02. Implementing the Context API

Okay, first things first.

Let’s take all the theme related complexity outside of our main App Component.

ezlk3BhbsT4QLsjJobmLVFMF9ztfb7U1sGGG
ThemeContext and ThemeProvider

To do this we’ve started by creating a ThemeContext using the React.createContext().

Then we’ve created a stateful component called ThemeProvider which will handle the state, the changeTheme method which is specific to this theming concern.

In the render method we’ll return the <ThemeContext.Provider> with the value props which self-contains whatever we want to propagate. This Component will embrace the { this.props.children } using the render props pattern.

By the way, if you want to know more about the render props pattern don’t miss my article about it here.

This way we can inject into everything that the <ThemeProvider /> embraces the value props with our state and changeTheme method.

Okay, next step is to clean all the props ? we’ve passed in our top down parent to child flow and, very important, to wrap the return of our App Component in our <ThemeProvider/> component — this will give “context” to our App ?.

RTL2t1GEAdEdAni6TwyC6SPN6LHF815ZyXzX

It’s so much cleaner now, everyone! ❤️ I’m so happy with this! ?

Let’s focus on our Button Component:

IeENT3TT5mmn6El3raVFbw2PSDuw8f4XayxP

Well, here we’ve just connected the <ThemeContext.Consumer> Component and inside of it we’ve passed a function to be rendered as a child with the context.

For those of you who aren’t aware this <> </> notation is the same as doing<React.Fragment>;</React.Fragment>.

03. Conclusion

I had so much fun with this, everyone! We’ve been able to encapsulate all the theming logic inside a proper component called <ThemeProvider>.

We’ve injected the context where we needed it. In this case it was in the <App> Component but it could be done anywhere above the place we want to consume the data.

In the end, we’ve consumed the data at the required point. In this case it was in a Button Component.

We’ve cleaned our app from all the top-down props flow.

It’s a win-win, my friends! ?

Thank you very much, and always remember to “Be Strong and Code On!” ?

04. Bibliography

01. React Documentation

evedes, Jan2019