Managing global state with React Context
05 June 2019
We’ve all been here before as React Developers. We’ve bootstrapped an application, created many parent-child components along the way, and realized how time consuming managing data flow through props can be. Applications eventually scale as business requirements change and evolve , and the problems being to quantify, leading to bugs and eventually a broken down codebase hanging by the thread of inefficiencies.
HOC (in short, Higher Order Components) presented a unique pattern, emerging from React’s compositional nature, to stitch together what otherwise would have ended up as deeply nested components, by using re-using component logic.
Think of it as a function that returns a new component.
Ultimately, this led to libraries such as Redux and Mobx as solutions for managing state in containers and mapped to components in the form of state and actions using HOCs.
Redux’s connect() is a great example of this. It connects the component to a Redux store and binds the state and actions to props.
So where does React Context come into this?
Context provides a way to share values between components, without prop drilling, but through a Provider/Consumer pattern.
Think of a “global” object that can be shared across components.
Here are some potential use cases:
- User Authentication
- Themes
- Locale
While this can be achieved using React/Redux, we avoid the use all together of a third party library and still avoid passing props through intermediates.
Function as a child
We’ll use the render prop to receive the context value and return a React node.
Use Case
Let’s consider a use case for utilising the Context API
Locale
Say we have an application that requires translations across three languages (English, Spanish, Portuguese).
We can pass our labels through a global store, in this case, a locale provider that wraps the entire application, and consume the values only where required within the component.
First, let’s create our folder structure for the project
First, I'll create an object containing our languages as a key prop.
I’ll then create a seperate file /context/index.js to initiate createContext
Create the class component for our provider:
Add the constructor:
Create a method which will bind the new locale to state. Remember we will shallow copy the previous state, and return a spread operation containing our new locale object
Create our render method and bind a new function (toggleLang) to our class method.
Export our class component (can also be declared at class creation)
Within our index.js, we will import the LocaleProvider and pass LocaleContext.Consumer as a child component
Our app should look something like this.
https://codesandbox.io/s/laughing-dew-trpsi