React Context — When and Why should you use it?

Akshar Mistry
4 min readAug 10, 2019

Sometimes there might come a scenario where an event in one component (e.g. a button click, change of text etc.) should trigger the changes in another component which is far far away from it in the DOM hierarchy.

Let’s just say we have a dropdown for currency which is a component in Header and changing it should change the currency values of items in our list component which is situated far down in our DOM hierarchy.

How to achieve this?

Option 1 — Maintain state at the main component level

One way is to state at the main component( which is a parent of both Header Component and the Body Component where the list resides). But that might not be the correct approach as it requires us to maintain state at a higher level and drill down same set of props till the lowest level required. This basically makes out code more cumbersome.

Option 2 — Maintain the state using redux

Another way is to store the currency value in the redux state and dispatch actions trigger the update. But it seems like an overkill for such a small functionality!

Option 3 (The one where we focus) — Using Context

You can create a context which globally shares data among the react components.

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

Instead of passing props from the main component down to its parent, grand parent and so on ( also called as Prop Drilling), you can create a context which lets you use that data globally among your components without drilling down props from parent to child.

Let’s try solving out currency dropdown problem mentioned above using Context.

Using Context :

Creating context is damn easy!!

Here you can pass any value into the createContext()method. It can be a string/number/boolean/object.

Using this context we need to create a Provider and a Consumer.

  • Provider : The component that provides with the value to be consumed amongst other components. Provider has a value prop
  • Consumer : The component that subscribes to the value of the provider. All Consumers are descendants of the Provider component and re-render when the value prop of the Provider changes.

Creating the Provider

We create a provider using myCurrencyContext.Provider and pass in a default value to it. This value will act as a global value and be consumed by our consumers(which will be the descendants wrapped inside myCurrencyContext.Provider).

NOTE: We create a CurrencyContextProvider component so that we can maintain the state of the context and add callback methods to set the currency value and get the currency rate. THIS IS JUST FOR A BETTER WAY OF WRITING AND IS TOTALLY OPTIONAL

Wrapping our consumer components inside the provider

Our components which require this data are deeply nested in HeaderComponent and ListComponent respectively.Wrapping these components will enable us to use the data provided by out Provider.

Creating the Consumer

Consumer in HeaderComponent

myCurrencyContext.Consumer provides us access to the global context which we defined while defining myCurrencyContext = React.createContext() .It will now hold the value passed by the Provider. Using this context we can call the setCurrentCurrency and getCurrencyRate methods.

Clicking on the respective dropdown values will trigger the setCurrentCurrency() which will set the currency. In the ListComponent, we can then call the getCurrencyRate() method which will give us the converted value.

ListComponent that consumes the context

Our ListComponent will consume the context and pass it to the immediate child component ListItemComponent

ListItemComponent uses the context.getCurrencyRate() to get the converted currency rate.

Link to the demo

Some More Examples

Some more places where context can be useful:

  • Passing Auth Data among various components
  • Changing the app theme colour
  • Change preferred language of the user

Conclusion

Context is primarily used when some data needs to be accessible by many components at different nesting levels.

Context is suitable where there are very less re-renders and light weight functionality. THIS IS NOT A REPLACEMENT/ALTERNATIVE TO REDUX

--

--