By Hemanta Sundaray on 2022-07-30
Context is one of the many ways React apps share state across many components without manual prop drilling.
The React Context API uses a Provider and a Consumer pattern to share data throughout an application. The provider role is played by a React component that makes data available to its descendant components. When one of those descendants accesses the shared data, it becomes a consumer.
To use the React Context API, we start by creating a React Context object, a named object created by the React.createContext() function.
Context objects include a .Provider property that is a React component. It takes in a value prop to be stored in the context. That value then becomes available to all its descendant components.
In the example below, we create React.createContext to create a new context. Then we store the context in a variable named ThemeContext and export it as a named export.
Next, we wrap the components returned by the App component in a ThemeContext.Provider component, with a value prop set to the darkModeTheme object containing the React state (darkMode) and its corresponding state updater function (setDarkMode).
import React, { useState, createContext } from "react"
import { Route, Switch } from "react-router"
import About from "./components/About"
import Blog from "./components/Blog"
import Navbar from "./components/Navbar"
import Footer from "./components/Footer"
export const ThemeContext = createContext()
const App = () => {
const [darkMode, setDarkMode] = useState(false)
const darkModeTheme = {
darkMode,
setDarkMode,
}
return (
<ThemeContext.Provider value={darkModeTheme}>
<div className="app-wrapper">
<Navbar />
<main className={darkMode ? "main-dark" : "main-light"}>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/blog">
<Blog />
</Route>
</Switch>
</main>
<Footer />
</div>
</ThemeContext.Provider>
)
}
export default App
Child components can subscribe to a Context’s value from their closest parent Provider with React’s useContext() hook. The useContext() hook accepts the context object and returns the current value of the context. Components subscribing to a context will receive the value for the Provider closest to them in the application tree.
import React, { useContext } from "react"
import { ThemeContext } from "../App"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faSun } from "@fortawesome/free-solid-svg-icons"
import { faMoon } from "@fortawesome/free-solid-svg-icons"
const Toggle = () => {
const { darkMode, setDarkMode } = useContext(ThemeContext)
const theme = darkMode ? "light" : "dark"
const circleClickHandler = theme => {
setDarkMode(!darkMode)
document.documentElement.className = theme
}
return (
<div className="toggle-wrapper">
<div className="toggle" onClick={() => circleClickHandler(theme)}>
<div>
<FontAwesomeIcon icon={faSun} className="sun" />
</div>
<div>
<FontAwesomeIcon icon={faMoon} className="moon" />
</div>
<div className={darkMode ? "circle-dark" : "circle-light"}></div>
</div>
</div>
)
}
export default Toggle
Note: The
Togglecomponent is inside theNavbarcomponent.