In this tutorial, we will explore the creation and utilization of context in React applications. Context provides a way to pass data through the component tree without having to pass props down manually at every level. It's an essential tool for managing state and helps simplify the flow of data through your application.
What you will learn:
- How to create a Context object
- How to use a Provider to make the Context value available to your components
- How to consume the Context data in your components
Prerequisites:
- Basic knowledge of JavaScript
- Understanding of React and its component-based architecture
- Familiarity with ES6 syntax and features
To create a Context object, we use React's createContext
function, which returns an object with Provider
and Consumer
components.
import React from 'react';
// Create a Context object
const MyContext = React.createContext(defaultValue);
The defaultValue
is optional and will be used if a component does not have a matching Provider above it in the tree.
A Context Provider is a React component that allows consuming components to subscribe to context changes. You can place it anywhere above the components that need to access its value.
<MyContext.Provider value={/* some value */}>
There are several ways to consume the context data in your components:
Consumer
component:<MyContext.Consumer>
{value => /* render something based on the context value */}
</MyContext.Consumer>
useContext
Hook:const value = React.useContext(MyContext);
Here is an example of how to create and use context in a simple React app:
import React from 'react';
// Step 1: Create a Context object
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Step 2: Use a Provider to pass the current theme to the tree below
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// A component in the middle doesn't have to pass the theme down explicitly anymore
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// Step 3: Consume the context value
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
In this example, ThemeContext.Provider
provides the current theme to the component tree below it. Then, ThemedButton
uses the contextType
property to consume the current theme from the context.
In this tutorial, we learned how to create and provide context for React components. We created a Context object, used a Provider to make the Context value available to the component tree, and consumed the Context data in a component.
Next steps for learning:
- Learn more about Context API from the official React documentation
- Practice handling more complex state with Context
- Learn about other state management libraries like Redux or MobX
Exercise 1: Create a context that provides a user object (with properties name
and age
) to the component tree. Make a Profile
component that consumes this context and displays the user's name and age.
Exercise 2: Expand on the previous exercise. Add a button in the Profile
component that, when clicked, increases the user's age by 1.
Solutions:
// Create UserContext
const UserContext = React.createContext();
// Provide the context value
<UserContext.Provider value={{ name: 'John', age: 25 }}>
<Profile />
</UserContext.Provider>
// Consume the context value in Profile component
function Profile() {
const user = React.useContext(UserContext);
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
</div>
);
}
useState
hook to handle the user's age:// Inside your component that provides the context value
const [user, setUser] = React.useState({ name: 'John', age: 25 });
// Provide the context value
<UserContext.Provider value={{ user, setUser }}>
<Profile />
</UserContext.Provider>
// Consume the context value in Profile component and add a button to increase age
function Profile() {
const { user, setUser } = React.useContext(UserContext);
const handleAgeIncrease = () => {
setUser({ ...user, age: user.age + 1 });
};
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<button onClick={handleAgeIncrease}>Increase Age</button>
</div>
);
}