You've arrived here since you're attempting to comprehend Context API. So, let's have a look at what the context API is all about.
Context API
According to the official documentation, Context API provides a way to pass data through the component tree without having to pass props down manually at each level.
Context API serves as a global store for data, which any component can access. It handles the state that is necessary in numerous components, in simple terms.
The Context API solves the issue of prop drilling and state Uplifting.
So what is Prop Drilling?
Issues
Prop Drilling
to begin with, a component can be supplied as a Parameter in react, which is known as Prop.
Proper drilling is defined as a circumstance in which the same data is sent at nearly every Component due to requirements in the final Component. we are passing on data through the components which don't need those data
Component B does not require the prop, yet it has been provided to Component C.
State Uplifting
Consider 3 component
A
/ \
B C
Component C has data that component B required. Because of react's unidirectional data flow characteristic, we can't pass data to siblings. So the standard way is to simply lift the data to its parent component, Component A.
Let's dive into coding.
Context API in Depth
Context API involves three steps
- Creating Context
- Creating Context Provider
- Consuming the Context
Creating Context
Context Can be Created using the createContext
method.
const themeContext = createContext({});
We can initialize Context with a value while creating it.
Creating Context Provider
A Provider is required for every context, and this Provider must wrap all components that will consume the context. Sneak peek of Provider Code:
<themeContext.Provider value ={value}>
{/*code*/}
</themeContext.Provider>
Although the preceding code will suffice, we can make it more efficient by creating a provider wrapper function like this.
export const ThemeContextProvider = ({ children }) => {
const themeData = {
darkTheme: { color: "#EEEEEE", backgroundColor: "#161616" },
lightTheme: { color: "#161616", backgroundColor: "#EEEEEE" }
};
const [theme, setTheme] = useState(themeData.lightTheme);
return (
<themeContext.Provider value={{ themeData, theme, setTheme }}>
{children}
</themeContext.Provider>
);
};
we have made a function which returns context.provider
<themeContext.Provider value={{ themeData, theme, setTheme }}>
{children}
</themeContext.Provider>
here children
means any element can come in between the opening tag and ending tag.
Note: in
value
you can pass either one parameter or multiple parameters in form of an object
The most common practice is to place all the providers in index.js
Combined Code Till Now:
import { createContext, useState } from "react";
const themeContext = createContext({});
export const ThemeContextProvider = ({ children }) => {
const themeData = {
darkTheme: { color: "#EEEEEE", backgroundColor: "#161616" },
lightTheme: { color: "#161616", backgroundColor: "#EEEEEE" }
};
const [theme, setTheme] = useState(themeData.lightTheme);
return (
<themeContext.Provider value={{ themeData, theme, setTheme }}>
{children}
</themeContext.Provider>
);
};
let's go to App.js
export default function App() {
return (
<div className="App">
<h1>Toggle Day Night</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem,
quasi quos accusamus hic eaque autem ipsum unde. Qui possimus libero
vero, obcaecati exercitationem sit sequi enim labore amet ab! Deserunt!
</p>
<button>Light</button>
<button>Dark</button>
</div>
);
}
Consuming Context
context has been created. and context's Provider has wrapped <App/>
so now the final step is to Consume the context
Using the usecontext
method, we can get the value of the context.
const {theme,setTheme,themeData}= useContext(themeContext);
we can onClick
on buttons like this
<button onClick={() => setTheme(themeData.lightTheme)}>Light</button>
<button onClick={() => setTheme(themeData.darkTheme)}>Dark</button>
then
<div className="App" style={theme}>
Combined Code of App.js
import "./styles.css";
import { useContext } from "react";
import { themeContext } from "./Context";
export default function App() {
const { theme, setTheme, themeData } = useContext(themeContext);
return (
<div className="App" style={theme}>
<h1>Toggle Day Night</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem,
quasi quos accusamus hic eaque autem ipsum unde. Qui possimus libero
vero, obcaecati exercitationem sit sequi enim labore amet ab! Deserunt!
</p>
<button onClick={() => setTheme(themeData.lightTheme)}>Light</button>
<button onClick={() => setTheme(themeData.darkTheme)}>Dark</button>
</div>
);
}
Congratulations you had made theme changing app
Final View: