What is Context?
At its core, Context is a way to share data between components without explicitly drilling through components props. It's a global state management system within your React application.
When to use Context?
You should consider using Context API when you have data or Settings that need to be accessed by multiple components at different levels of your Application's component hierarchy. This may be applied to features like User Authentication, theme preference, language settings etc.
Implementation
To understand clearly how the Context API works, We'll create a simple Theme functionality that is commonly used in many React Applications.
Let's go through the steps of implementing the Context API:
1. Create A context
Create a folder store in your src directory and inside create a file called: ThemeContext.js and import the necessary dependencies:
import React, { createContext, useState } from 'react'
We'll create and export a theme Context that we'll use to share data across our Application.
import React, { createContext, useState } from 'react'
export const ThemeContext = createContext()
2. Provide the Context
After creating the context, we now have to create a Provider. This is a typical component that wraps the portion of your application where you want to make certain data available to other components. In our case, we'll wrap our Provider in index.js as we want the Theme context to be accessed globally.
To create a Provider, we'll simply create a react component and name it ThemeProvider. We then pass props to the component named children.
export const ThemeProvider = ({ children }) => {
}
In the provider, we initialize a state variable and set it to false:
export const ThemeProvider = ({ children }) => {
const [isDarkTheme, setIsDarkTheme] = useState(false)
}
Create a function toggleTheme that will update the state every time its called.
export const ThemeProvider = ({ children }) => {
const [isDarkTheme, setIsDarkTheme] = useState(false)
const toggleTheme = () => setIsDarkTheme(prevTheme => !prevTheme)
}
3. Consume the Context
To consume the Context, return the provider with the data you want to share with other components and wrap the children props inside.
export const ThemeProvider = ({ children }) => {
const [isDarkTheme, setIsDarkTheme] = useState(false)
const toggleTheme = () => setIsDarkTheme(prevTheme => !prevTheme)
return (
<ThemeContext.Provider value={{ isDarkTheme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
And there you go! You've created a context API in React.
4. Using the Context In the App
To be able to access the data in the Context API, we will have to wrap the portion of our Application with the ThemeProvider for the components to consume the data. So we'll wrap the App component with the Provider.
Open your index.js
file, import the ThemeProvider
and Wrap the App component with it.
Here's how the index.js
file should look:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ThemeProvider } from './store/ThemeContext';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</React.StrictMode>
);
With this setup, we can access the data throughout the entire application.
5. Use Case 1
In the src directory, create aButton.js
file and inside import the following dependencies:
import React, { useContext } from 'react'
import { ThemeContext } from './store/ThemeContext'
import './App.css'
Make sure you have App.css
in the same folder for styling the button.
Create a React component called Button and add a button element to it:
import React, { useContext } from 'react'
import { ThemeContext } from './store/ThemeContext'
import './App.css'
const Button = () => {
return (
<button>
change Theme
</button>
)
}
export default Button
Import the data from isDarkTheme
and toggleTheme
from ThemeContext
API.
import React, { useContext } from 'react'
import { ThemeContext } from './store/ThemeContext'
import './App.css'
const Button = () => {
//Consuming the Data from The context API
const { isDarkTheme, toggleTheme } = useContext(ThemeContext)
return (
<button>
change Theme
</button>
)
}
export default Button
Now that we have accessed the data, we can apply it to our button element. We'll add the onClick
event to the button and some styling.
import React, { useContext } from 'react'
import { ThemeContext } from './store/ThemeContext'
import './App.css'
const Button = () => {
const { isDarkTheme, toggleTheme } = useContext(ThemeContext)
return (
//adding onClick Event and the theme custom styles to the button
<button onClick={toggleTheme} className={`${isDarkTheme ? 'lightBtn' : 'darkBtn'}`}>
change Theme
</button>
)
}
export default Button
6. Use Case 2
Open App.js
and add the following dependencies:
import { useContext } from 'react';
import './App.css';
import Button from './Button';
import { ThemeContext } from './store/ThemeContext';
Inside the App component, import isDarkTheme from the ThemeContext API.
function App() {
const { isDarkTheme } = useContext(ThemeContext)
}
return a div component with the following:
return (
//Added the styles based on isDarkTheme Boolean value
<div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}>
<h1>Theme Context Api</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.</p>
<Button />
</div>
);
Here's how the entire file looks:
import { useContext } from 'react';
import './App.css';
import Button from './Button';
import { ThemeContext } from './store/ThemeContext';
function App() {
const { isDarkTheme } = useContext(ThemeContext)
return (
<div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}>
<h1>Theme Context Api</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.</p>
<Button />
</div>
);
}
export default App;
Finally, open App.css
and paste the following styles. You can modify them to suit your specific needs.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.App {
padding: 50px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 20px;
height: 100vh;
}
.darkTheme {
background-color: black;
color: aliceblue;
}
.lightTheme {
background-color: aliceblue;
color: black;
}
button {
padding: 10px;
border-radius: 10px;
border: 1px solid;
cursor: pointer;
font-size: 16px;
}
.darkBtn {
background-color: black;
color: aliceblue;
}
.lightBtn {
background-color: aliceblue;
color: black;
}
Run the App
When you run the App in the browser, the theme will change on each button click demonstrating that the data is being shared between the Button component as well as in the App component.
Conclusion
In this article, we explored the concept of using Context API to efficiently share data between components while avoiding prop drilling. To help you understand how the Context API works, we implemented a simple functionality that is commonly used in many React Applications and verified that we were able to share global state across your application.
GitHub Repo
Never miss an article, subscribe to our newsletter to receive regular updates, fresh insights, and exclusive content.
Top comments (0)