React is a popular JavaScript library for building user interfaces, and one of its core principles is the concept of state management. State allows components to keep track of data and update the UI accordingly. In this blog post, we will explore the powerful useContext hook, which simplifies state management in React and provides a delightful developer experience.This blog targetting the audience who just wants to learn about useContext
hook for their project or those who want to refresh their concepts
Understanding The Problem Of Prop Drilling
React's useContext hook addresses the problem of prop drilling, which occurs when we need to pass data down multiple levels in the component tree. Prop drilling can make the codebase hard to maintain and lead to performance issues. The useContext hook simplifies this process by allowing us to share state or other values across components without the need for intermediate component props.
Example: Imagine a music player application with components like App, Player, Playlist, and Song. The App component holds the state for the currently playing song, and we need to pass this state down to the Song component for display. Without useContext, we would have to pass the currently playing song as props from App to Player, then from Player to Playlist, and finally from Playlist to Song. This creates a tangled web of props and makes the code difficult to maintain.
Lifting State Up Understanding the Jargon Before diving into the useContext hook, it's important to grasp the concept of "lifting state up." In React, "lifting state up" refers to the practice of moving the state from a lower-level component to a higher-level component, making it accessible to multiple child components. By lifting state up, we centralize the management of that state, simplifying the data flow and reducing the complexity of passing props between components.
If you are not too familiar with "lifting state up in react" then I will strongly recommend you to learn the basics at least first(it will hardly take 15-20 minutes) and then continue learning useContext
hook.
🎉Introducing useContext
for Elegant State Management
Let's explore the steps and best practices for using the useContext
hook effectively in functional components:
Step 1: Import the necessary modules
Start by importing React
and the `useContext` hook from the React library.
import React, { useContext } from 'react';
Step 2: Creating a Context
To get started, we need to create a context using the createContext
function provided by React. This function returns a context object that consists of two components: Provider and Consumer. We will focus on the Provider component for now.
const MyContext = React.createContext();
// you can use any name for creating context in place of MyContext
STEP 3: Create a Context Provider
import React, { createContext,useState } from 'react';
const MyContext = createContext();
const MyContextProvider = ({ children }) => {
// Define the shared state and functions here and pass them in the value{}
// lets take an example of counter
const [count, setCount] = useState(0); // Shared state
const incrementCount = () => {
setCount(count + 1);
};
const decrementCount = () => {
setCount(count - 1);
};
return <MyContext.Provider value={{ count,setCount, incrementCount, decrementCount}}>
{children}
</MyContext.Provider>;
};
export {MyContext, MyContextProvider}
Step 4: Wrap the Components with the Provider
💡This is a very crucial step where beginners tend to do mistake
import React from 'react';
// importing context provider
import { MyContextProvider } from './MyContext';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const App = () => {
return (
<MyContextProvider>
<ComponentA />
<ComponentB />
</MyContextProvider>
);
};
export default App;
Step:5 Access the Context in the Consuming Components
In the components where you want to access the context value, use the useContext
hook to consume the context.
import React, { useContext } from 'react';
// importing context
import { MyContext } from './MyContext';
const ComponentA = () => {
//👉passing MyContext in useContext hook as argument
const { count, incrementCount } = useContext(MyContext); // Access the shared state and functions
return (
<div>
<h2>Component A</h2>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
};
export default ComponentA;
This is all you need to know about useContext
hook in react. I would recommend you learn about the refactoring techniques I discussed below.
⭐Refactoring useContext in React: Consuming Context within the MyContext File.
Imagine you have many components in which you need to consume value from context. For that you have to import context
every time which can be a little messy and frustrating so to overcome that situation you can refactor the useContext
hook by consuming the context in the MyContext
file itself, eliminating the need to import it in every single component:
Let me show you example by refactoring the above code :
- The first change you need to make is importing
useContext
in context file it self
import React, { createContext, useState, useContext } from 'react';
Define a custom hook, let's call it
UseMyContext
, which consumes the context and returns the shared state and functions:```javascript import React, { createContext,useState } from 'react';
const MyContext = createContext();
export const MyContextProvider = ({ children }) => { // Define the shared state and functions here and pass them in the value{}
// lets take an example of counter
const [count, setCount] = useState(0); // Shared state
const incrementCount = () => { setCount(count + 1); };
const decrementCount = () => { setCount(count - 1); };
return {children} ; };
export function UseMyContext (){ return useContext(MyContext) }
Consuming the Context in Components:
```javascript
import React from 'react';
// 👉 importing UseMyContext and no need to import useContext from react
import { UseMyContext } from './MyContext';
const ComponentA = () => {
// 👉 Access the shared state and functions using custom hook in context hook
const { count, incrementCount } = useMyContext();
return (
<div>
<h2>Component A</h2>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
};
export default ComponentA;
Conclusion 👋
The useContext
hook is a powerful tool for simplifying state management and context consumption in React applications. By following the steps outlined in this article, you can effectively create and consume context, access shared state and functions, and streamline your React codebase. Leveraging the useContext hook empowers you to build scalable, maintainable, and efficient applications. Start harnessing the power of useContext today, and unlock the full potential of React's Context API.
Happy coding!🎉