When I started to learn React, I was overwhelmed by the concept of Context so I immediately forgot everything I read and decided I would just never use it. Then I had to drill state and setState 5+ components deep in a bootcamp project and I thought maybe I should give Context another chance. At that point I was more familiar with state and component trees and armed with that confidence (and a playlist of youTube videos) I set out to understand and implement Context in my app, and lets just say I nailed it. Here is my simplified explanation for anyone just starting out with Context.
What is Context?
Context is a way of accessing data through your whole component tree without having to pass props down manually at every level. Once Context is created you can import it in any component you wish to access the data. Simply put, its like creating a global state.
When to use Context?
I had read a few suggestions to use Context sparingly which was part of the reason I didn't spend time learning it initially, and frankly, I don't heed that advice now. For me, Context makes my code feel a lot cleaner and better managed. If I need access to a piece of state in 3 or more components, I'm using Context. That is especially true if I'm going update the state and I want the change to persist across all pages of my app. Common examples people use for Context are setting a dark theme and referencing if a user logged in. I personally use it often with data I have fetched from an API.
How to do it:
We will need to do two things to use Context:
Establish Context with
createContextand wrapping components that will use the context in aContext.Provider.Importing the context in the consumer component with
useContext. (With a bonus method of importing Context at the end!)
First, decide where you want to store your context data. I like to put it in a separate Context component and import it to my App component. This keeps my code tidy but you can also establish Context directly in your App component. Like state, you just want to make sure it lives in a parent to all the components that will eventually import the data. If you are storing context in a Context component like me, you will need to pass it a {children} prop.
In the Context component import createContext from react with your other hooks. In this example, I'm going to useState to store the data we will pass as context to the consumer components.
Next we will need to use the createContext hook to declare our context outside our Context component using the createContext() function. We declare the context outside the Context component because we are going to export it for use in our consumer components.
Your code should look like this so far:
Now we need to tell React what data our DataContext we just created will hold. This is usually where I would useEffects to fetch data from an API and assign it to a state variable but to keep our example clean and simple I'm just going to declare the state with a default value of an array of numbers.
From here we create the 'provider component' for the DataContext as a return from our Context component. This DataContext.Provider component takes one prop called value which we assign data (our state from the previous step) and wraps around the {children} prop we gave to our Context component earlier. Like this:
What if we wanted to use setData in another component of the app? Well, we could declare another context and call it something like UpdateDataContext and wrap both our child and DataContext.Provider in the UpdateDataContext.Provider. If this were unrelated data, I would probably go ahead and do that.
Instead since setData is part of our data state, in our DataContext.Provider we set our value to an array of [data, setData]. This will pass both our data and setData function to our children components in our single DataContext.Provider.
The final step in our provider component process is to import our Context component to our App component and wrap it around all the children, or 'consumer components' we want to pass our data to.
At this stage, our data and setData are available to all the components in our app without having to pass any props! Amazing, but how do we access them? Thats step 2...
useContext
Lets go directly to ComponentC, bypassing components A and B. Here we will import useContext from react as well as our DataContext from our Context component.
We'll then take the useContext hook, pass it DataContext and declare the variables we will be setting the data to in ComponentC.
Viola! You now have access to your data state and setData function in ComponenetC to use as you wish with out having to pass the prop through multiple components.
TLDR:
To recap, in order to create globally accessible state with Context in your app we:
Created the Context Provider by:
- Creating a Context component and passing it a prop of
{children}. - Importing
createContextfrom react - Declaring and exporting our
DataContextfromcreateContext()outside the Context component. - Declaring the state we will use as our context data inside the Context component.
- Wrapping our
{children}in theDataContext.Providerthat has one prop of value and setting it to the state we declared in step 4. - Exporting our Context component and importing it in the App component to wrap around all the components in our app.
Accessed the Context in our consumer component by:
- Importing
useContextfrom react andDataContextfrom our Context component in our consumer component. - Assigning our
dataandsetDatavariables usinguseContextand passing it ourDataContext.
Bonus!
The above works just fine but one more thing I like to do to streamline my code is rather than importing useContext in my consumer, I export a function that returns useContext() from my Context component so I only have to import this function to to access my data in my consumer components. This is what it looks like in both Context and ComponenetC.
What we did was:
- Import
useContextin theContextcomponent and remove it fromComponentC. - Export the
useDatafunction that returnsuseContext(DataContext). - Imported
useDatain ComponentC.
Thats it! After setting up Context once or twice I felt a lot more confident but I did reference my notes on future tries so write your own workflow or save this blog for future reference!







Oldest comments (4)
I have one question. is this re-render the componentA and B while updating the value.
Hi! Any component that uses the "data" state that we assigned to our context will re render if you assign a new array with the setData function.
i am not sure. i have some doubt. if i update(setState) the value in componentC does it reRender the component A and B?
If the state is updated inside the context component, it will cause a re-render on all the components that use the context and consume that state via the useContext hook. This is because, whenever the state inside the context changes, React will trigger a re-render on all the components that are subscribed to that context. However, components that do not use the context will not be affected by the state change and will not be re-rendered.