Hey coders, in this blog we are going to discuss how to use context in React for passing data between components
First, we have to understand how we can share data between different components without using Context, we can do it using Props and we are going to learn when to use Props and when to use Context for data(state, functions, etc.) sharing.
Suppose we have a simple state in our App.jsx file that is responsible for changing the theme(either the dark theme or light theme) of an App based on when a user clicks on a button that is in the Navbar of our app, Now the problem is that our state is in the App.jsx and button which changes the state is in Navbar how can we get the data(in this case setState) in the Navbar to change the theme on user click, there are 2 solutions to this problem either we can move the state into Navbar or we can pass it using props
We can follow the first step also but let us assume that we want to keep the state in the App.jsx file only
First, let's see the code of the App.jsx
import React,{useState} from 'react';
import Navbar from '../Navbar';
import MainSection from '../MainSection';
import Footer from '../Footer'
const App = () => {
const [theme,setTheme] = useState(false);
return(
<div style={{backgroundColor : theme ? '#7f7f7f' : '#ffffff'}}>
<Navbar setTheme={setTheme}/>
<MainSection />
<Footer />
</div>
)
}
export default App
In this App.jsx we have set up the state theme using useState and set its default value to false and pass the setTheme function to Navbar using props
Now let's see the Navbar how can we use the passed data in this component to change the theme when the user clicks on the button
import React from 'react';
const Navbar = (props) => {
return(
<div>
<ul>
<li>Home</li>
<li>About</li>
<li>Services</li>
</ul>
<button onClick={() => props.setTheme(prevTheme => !prevTheme)}> </button>
</div>
)
}
So this is a simple way of managing state and passing data using props
Now let's see when we can pass data using props and when we should not
Suppose there is some state in the App.jsx and we want to use it in the first child of the first parent then how can we do it we have to pass data in the form of props to the grandparent and then the parent and then to the child which finally use it. But it's not the optimized or a good solution for a more complex React application as the grandparent and parent component are not using the passed data still they are accepting it via props which are rendered each time the state changes this problem of passing props between different components is called props drilling.
What happens if we have some state in the third grandparent and we want to use it in the child of the first grandparent we cannot pass it using props as they are not hierarchically related to each other in this case what we can do is move the state to App.jsx and then pass it using props to the respected components which are not we required every time we used it.
To solve all these problems, React introduced the concept of Context
Context API is a (kind of) new feature added in version 16.3 of React that allows one to share state across the entire app (or part of it) lightly and with ease.
React context API: How it works?
First, we have to create the context using React.createContext(). It returns a consumer and a provider. The provider is a component that as its name suggests provides the data to its children. Consumer as it so happens is a component that consumes and uses the state.
Now let us understand how to use it.
import React, { createContext } from "react";
const UserContext = createContext();
const ContextProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
function toggleTheme(){
setTheme(prevState => (prevState === "light" ? "dark" : "light"))
}
return (
<UserContext.Provider value={{ theme,toggleTheme }}>
{children}
</UserContext.Provider>
);
};
export {ContextProvider, UserContext};
In the above example, we first create a context using createContext and then provide the value we need to provide to other components in UserContext.Provider and export the Context and ContextProvider component
It is necessary to wrap the main.JSX (in vite ) or App.jsx component with ContextProvider so the Context can pass the data or states to other components.
import React from 'react';
import App from "./App"
import ReactDOM from "react-dom";
import {ContextProvider} from "./Context"
ReactDOM.render(
<ContextProvider>
<App />
</ContextProvider>,
document.getElementById("root")
)
Now we can consume the data in any component using the useContext Hook
import React, {useContext} from "react"
import {UserContext} from "./Context"
function Header(props) {
const {theme,toggleTheme} = useContext(UserContext) // we destructure it to get theme and toggleTheme passed using Context Provider in value
return (
<header>
<h2>{theme === "light" ? "Light": "Dark"} Theme</h2>
<button onClick={toggleTheme}>Set Theme</button>
</header>
)
}
export default Header
Now we can pass data using Context from Producer to Consumer even if they are not in hierarchy order and directly from Provider to Consumer this solves the problem of Props drilling and also our data can be managed in only one content normally in the context file. This provides a cleaner way of maintaining code and implementing the DRY (Don't Repeat Yourself ) in our code.
You can read more about the Context at https://reactjs.org/docs/context.html
That's the end of the blog, If u like and learned something from it give it a like do follow me, and Share this with your colleagues
Social Media Links smlinks
Follow me on Twitter, Twitter ID: Arsalan_0101
Top comments (0)