Suggest an editImprove this articleRefine the answer for “How to create global state with useContext?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`useContext`** lets you create a "global container" of data through `Context`, giving any component in the tree access to that data without passing props "down the chain" (`prop drilling`). **Key point:** to do this you first create a context with `createContext`, then a provider that holds the state, and only then can any component read and change that state through `useContext(Context)`.Shown above the full answer for quick recall.Answer (EN)Image## What `useContext` does `useContext` lets you: > Create a "global container" of data (via `Context`) > Give any component in the tree access to that data > Without passing props "down the chain" (`prop drilling`) --- ## 1. Create a context ```javascript import { createContext } from "react"; // Create the context export const ThemeContext = createContext(); ``` A context is a "box" in which React will store data. Later you'll "pour" state into it and "spread" it across the app. --- ## 2. Create a **provider** (the component that holds the state) ```javascript import { useState, createContext } from "react"; // create the context export const ThemeContext = createContext(); export function ThemeProvider({ children }) { const [theme, setTheme] = useState("light"); const toggleTheme = () => setTheme((prev) => (prev === "light" ? "dark" : "light")); return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); } ``` What happens here: - We created a global `theme` state - We wrapped it in `<ThemeContext.Provider />` - We passed into `value` what we want to share (`theme`, `toggleTheme`) Now every child component inside `<ThemeProvider>` can access this data. --- ## 3. Wrap the whole app in the provider In `App.jsx` or `main.jsx`: ```javascript import { ThemeProvider } from "./ThemeContext"; import Page from "./Page"; function App() { return ( <ThemeProvider> <Page /> </ThemeProvider> ); } export default App; ``` Now **every component inside** `ThemeProvider` can use `useContext(ThemeContext)` and read / change the global state. --- ## 4. Use `useContext` in any component ```javascript import { useContext } from "react"; import { ThemeContext } from "./ThemeContext"; function Header() { const { theme, toggleTheme } = useContext(ThemeContext); return ( <header style={{ backgroundColor: theme === "light" ? "#fff" : "#333", color: theme === "light" ? "#000" : "#fff", }} > <p>Current theme: {theme}</p> <button onClick={toggleTheme}>Toggle theme</button> </header> ); } ``` That's it! The `Header` component now has access to the **global theme state**, even though it's stored "at the top" of the app, without passing it through props. --- ## How it works under the hood 1. `createContext()` creates a "communication channel" between components. 2. `<Provider value={...}>` makes the data available to all descendants. 3. `useContext(Context)` subscribes the component to updates of that context. → If `value` in the provider changes, React **re-renders all subscribers**. --- ## Important: `useContext` is not a silver bullet Although Context = "global state", you need to use it **carefully**: | Problem | Description | |---|---| | All subscribers re-render | On every change of the value in `Provider` | | Not suited for very frequently changing data | For example, an FPS counter or mouse position | | Better suited for "settings" | Theme, language, current user, auth | For frequently updated data it's better to use Zustand, Jotai, Redux, or to split contexts (so each one holds only one part of the state). --- ## Full project structure example ```javascript src/ ├─ context/ │ └─ ThemeContext.jsx ├─ components/ │ ├─ Header.jsx │ └─ Footer.jsx ├─ App.jsx └─ main.jsx ``` **ThemeContext.jsx** ```javascript import { createContext, useState } from "react"; export const ThemeContext = createContext(); export function ThemeProvider({ children }) { const [theme, setTheme] = useState("light"); const toggleTheme = () => setTheme((prev) => (prev === "light" ? "dark" : "light")); return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); } ``` **Header.jsx** ```javascript import { useContext } from "react"; import { ThemeContext } from "../context/ThemeContext"; export function Header() { const { theme, toggleTheme } = useContext(ThemeContext); return ( <header className={theme}> <h1>Theme: {theme}</h1> <button onClick={toggleTheme}>Toggle</button> </header> ); } ``` **App.jsx** ```javascript import { ThemeProvider } from "./context/ThemeContext"; import { Header } from "./components/Header"; export default function App() { return ( <ThemeProvider> <Header /> </ThemeProvider> ); } ``` --- ## Summary | Question | Answer | |---|---| | What does `useContext` do? | Lets you read data from the closest `<Context.Provider>` | | How to create global state? | Wrap the state in a `Context.Provider` and use `useContext` | | When to use it? | When data is needed in different places in the tree (theme, language, user) | | What to replace it with in complex cases? | Zustand, Redux, Jotai, Recoil, etc. | | How to avoid extra re-renders? | Split contexts and memoize `value` (via `useMemo`) |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.