Table Of Contents
Introduction
React offers the ability to build out web applications quickly. One of the details of this strategy includes passing data to different components in the DOM. This can consist of needed data to build features, states of a component, and anything you can think of.
Data In React
One great pattern in React is how data can be passed through the different components. However, this can get messy.
An application might be broken down like below.
A collection of components. Some of these components return other components. These are called parent components, and their children are nested components.
We can pass data back and forth throughout the lifetime of each component. Working with only props, for example, lets us pass data down the tree to the components that need it. However, this can present a problem.
Using props or properties is a great way to handle data. However, the deeper the component is buried, the more you have to pass the props down. This is called prop drilling.
Using the workflow above, we have a couple of nested components passing the Username
prop down the tree. The Page
and MainContent
props are just passing down the props used by the UserCard
component like a vertical game of telephone.
Now combine this with having to scale out your context to include hundreds of bits of data or state, which need to be passed down to various components at various levels of the tree, and we’ve got a problem.
Context in React
Context solves the problem by allowing us to pass down data without relying on continually passing props through components. Context in React should be used handling global data that does not have to change often. Using context to keep track of our username state improves the workflow by allowing components to use context as needed without passing it down the tree. Pictured below.
As illustrated above, we can provide the context to one component, and the children component will be able to access the context regardless of the level they are at. All without needing to have their parent components pass the data down.
Context In Use
So let’s look at an example of context. I created a small React app and just made some barebones components. The first file we should check out is the App
component.
There are some lines of note, as you’ve undoubtedly seen, and then some other stuff needed for using context. The first out-of-place thing is using the React function React.createContext()
, which we use to create a context object. We also made a provider for our context object and wrapped our Page
component in it.
Context works using Providers and Consumers. In this case, we are looking to provide the context to our app for consumption by the components. So we use the provider tag, which every context object has, to pass in the value
string to our nested components.
The value
attribute is a prop that the provider accepts and can pass down the tree. Many consumers can subscribe to one provider, and we’ll talk about that more.
We're not passing anything to the Page
component except the Header
and MainContent
components.
Let’s look at the Header
component.
The header is a regular old React component. However, we use the React hook React.createContent()
to subscribe to the UserContext
object that we import into this component from the App
component. We can now use the curly brackets to pass in the userNameContext
into the JSX being returned by the component.
Let’s look at another example. Below we have our MainContent
component.
Just another component with a nested component, UserBox
. Let’s look at what is in the UserBox
component.
The UserBox
component can do as our header did; import the context object, subscribe to the provider using the useContext
hook and pass in the context using that context object. This is cool because we’re using context two levels below from where it was created without passing props through subsequent components.
The app would look something similar to the below image. We can see the username string in the header
and the UserCard
components. I am not one for styling things effectively, so hold your judgments.
Conclusion
Changing the value of the state would cause a render for the other components subscribed to the context. So it could cause issues if the state is constantly changing. So context fits nicely with a global state that is not likely to change often.
The code for the above example can be found on my GitHub.
This has been an interesting learning experience. I’m happy to have gotten one of the fundamentals of React down on paper, so to speak. I hope this helps someone new coming into the React scene.
-George
Top comments (1)
Question: how can we change the value of the state stored in context? Will it trigger a re-render of the components subscribing to it? Also if one component changes it, will it reflect everywhere in every component using it?