The Context API: A Deep Dive (Part 1) - `createContext`, `Provider`, and `useContext` #97
📖 Introduction
Welcome to a new chapter in our journey! Having mastered routing with React Router, we now turn our attention to a new challenge: state management at scale. We'll begin by exploring React's built-in solution for sharing state between components: the Context API. In this first part, we will cover the three core concepts: createContext
, Provider
, and useContext
.
📚 Prerequisites
Before we begin, please ensure you have a solid grasp of the following concepts:
- React components and props.
- React Hooks, especially
useState
. - The problem of "prop drilling".
🎯 Article Outline: What You'll Master
In this article, you will learn:
- ✅ The "Why" of the Context API: Understanding the problem of prop drilling and how the Context API solves it.
- ✅
createContext
: How to create a new context. - ✅
Provider
: How to provide a value to a context. - ✅
useContext
: How to consume a context value in a component.
🧠 Section 1: The Core Concepts of the Context API
As your application grows, you'll often find that you need to share state between components that are far apart in the component tree. Passing props down through many levels of components (a problem known as prop drilling) can be cumbersome and make your code hard to maintain.
The Context API provides a way to share data between components without having to pass props down manually at every level.
The three core concepts are:
createContext
: This function creates a context object. You can think of this as creating a new "channel" for sharing data.Provider
: Every context object comes with aProvider
component. You use this component to wrap a part of your component tree and provide a value to the context.useContext
: This hook allows any component within aProvider
to subscribe to the context and get its value.
💻 Section 2: Deep Dive - Implementation and Walkthrough
Let's see how these three concepts work together.
2.1 - Creating a Context
First, let's create a new context. It's a good practice to create your contexts in a separate file.
// ThemeContext.js
import { createContext } from 'react';
const ThemeContext = createContext('light'); // 'light' is the default value
export default ThemeContext;
Here, we've created a ThemeContext
with a default value of 'light'
.
2.2 - Providing the Context
Now, let's use the Provider
to make a value available to our components. We'll do this in our App.js
file.
// App.js
import React from 'react';
import ThemeContext from './ThemeContext';
import Toolbar from './Toolbar';
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
export default App;
We've wrapped our Toolbar
component with the ThemeContext.Provider
and given it a value
of 'dark'
.
2.3 - Consuming the Context
Now, any component inside the Toolbar
can consume the context value using the useContext
hook.
// ThemedButton.js
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext';
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme === 'dark' ? '#333' : '#FFF', color: theme === 'dark' ? '#FFF' : '#333' }}>
I am a {theme} button
</button>
);
}
export default ThemedButton;
And here's our Toolbar
component:
// Toolbar.js
import React from 'react';
import ThemedButton from './ThemedButton';
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
export default Toolbar;
The ThemedButton
component will now have a dark theme, because it is consuming the value provided by the ThemeContext.Provider
in App.js
.
💡 Conclusion & Key Takeaways
In this article, we've learned about the three core concepts of the Context API: createContext
, Provider
, and useContext
. We've seen how they can be used to solve the problem of prop drilling and share state between components.
Let's summarize the key takeaways:
- The Context API provides a way to share data between components without prop drilling.
createContext
creates a new context.- The
Provider
component makes a value available to a context. - The
useContext
hook allows components to consume a context value.
Challenge Yourself:
To solidify your understanding, try to create a UserContext
that provides a user object to its children.
➡️ Next Steps
You now have a basic understanding of the Context API. In the next article, "The Context API: A Deep Dive (Part 2)", we will explore how to update the context value from a nested component.
Thank you for your dedication. Stay curious, and happy coding!
glossary
- Context API: A React API that allows you to share state between components without having to pass props down manually.
- Prop Drilling: The process of passing props down through multiple levels of nested components.
createContext
: A function that creates a context object.Provider
: A component that provides a value to a context.useContext
: A hook that allows a component to consume a context value.