Context in React Hooks

Debarshi Chaudhuri
Alien Brains
Published in
5 min readJul 8, 2020

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

When React version 16.3 came out it had an interesting feature, Context. Now, why was it introduced? To understand it let’s take up an example.

The Project

Fig 1: The sample project.

From Fig1 we can see that Component1 has many sub-components namely, Component2, Component 3, Component 4, and a Button.

When I click the button, the border-color of Component1 goes from red to black, the border-color of Component4 goes from black to red, and the button whose text was black on white alternates to white on black.

This change in color is achieved using state. My state is initially false and then at the press of the button, I alternate its value.

We can see that the button click affects only Component1, Component4, and Button. Component2 and Component3 remain unaffected by it.

Fig 2: Component1.

Component 1

This component holds the state dark and the function changeToDark using which we can alternate its value. Initially dark is false so the border-color is red in Component1 as you can see in Fig 2.

Component1 passes the state and the function as props to Component2.

Fig 3: Component2
Fig 4: Component3

Component2 and Component3

These two components have no functionality other than passing the props from the parent component to the child component. Component2 receives props from Component1 and passes it down to Component3. Component3 receives props from its parent Component2 and passes it down to Component4.

Fig 5: Component4

Component4

This component receives the props but only uses the dark property to change its border-color. When dark is initially false border-color is black and when we press the button the border-color changes to red as its value changes to true.

Fig 6: Button

Button

This component uses the value of dark to change its background-color and color property, and on clicking the button it calls the function changeToDark to alter the value of dark and simultaneously cause changes in the UI.

The Problem

As you can see from above that at every level we have to pass down the state dark and the function changeToDark associated with it. Now, this is a small project so it doesn’t matter that much to pass them down as props.

But the question is…

What if my project had like 30 sub-components in it?

What if there were multiple states and functionalities that I had to pass down to the sub-components?

Then it would become quite confusing to tackle so many props. And I had to pass it down through components that may have no use of it, like Component2 and Component3 in my case.

This problem is known as Prop Drilling.

Prop drilling (also called “threading”) refers to the process you have to go through to get data to parts of the React Component tree.

In this project, dark and changeToDark are the data and they have to reach the bottom-most level of my React Component Tree.

The Solution

The ContextAPI was introduced to overcome this problem regarding prop drilling.

For this, we need to create a context object using React.createContext()

Fig 7: MyContext

The value false is the default value of the context.

Fig 8: Component1 restructured using Context.

Component1

In fig 8, I have imported MyContext in Component1 to use it. Now every Context comes with a Provider React component. As its name suggests it “provides” values to its sub-components. In this case MyContext.Provider has a value which is a property containing the state dark and the function changeToDark as an object. The sub-components when they try and access the value, they use the value which is provided by the nearest context Provider, in this case, which is Component1. We can also see that earlier, we had to pass the data down to Component2 as props but, now we don’t do it.

Fig 9: Component2 restructured
Fig 10: Component3 restructured

Component2 and Component3

Earlier Component2 and Component3 had no use of the props dark and changeToDark but still, we had to pass it down since the components, which are below them in the component tree, require it. But now we have don’t have to do it.

When we use Context we don’t have to pass down the data as props. Hence Prop Drilling which was a major disadvantage had been avoided.

Fig 11: Component4 restructured.

Component4

React Hooks provided a function useContext, this function allowed us to access the value which is provided by the nearest context provider. In this case, the nearest context provider is Component1 hence the values that are provided by it are used. Since value is an object we can access the state using value.dark and the function using value.changeToDark .

As the current context value is determined with dark which is my state, whenever it is changed it causes a re-render in all the functions which use it.

Fig 12: Button restructured.

Button

Similarly, in this case too the function useContext is used to access the value of the nearest context provider and its values are used accordingly.

The functionality of Button has remained the same, except we have used Context now.

Conclusion

Throughout the entire process, the logic of the code has not changed. Instead, we used a new feature to overcome the problem of prop drilling that we were dealing with earlier.

Similar to Context, there is Redux which deals with the same problem regarding props. Context basically provides us a way to pass down data at different component levels without using props and this is the reason why Context Matters.

Thanks for reading!

--

--