Day 9 of 100 Days of Code — Understanding the React Context API
Source: Dev.to
React Context API – A Quick Overview
If you’ve spent some time working with React, you’ve probably heard about the Context API but may not have fully understood when or why to use it.
The Context API is a built‑in feature of React that lets you share data across components without having to pass props through every level of the component tree. It becomes particularly useful when multiple components need access to the same data, such as:
- Theme settings
- Authentication status
- App‑wide configurations
Learning goal for Day 9: understand the Context API, an essential tool for building clean, maintainable React applications and avoiding the complexities of prop‑drilling in larger projects.
What Exactly Is the React Context API?
“A centralized, React‑native way to manage shared state or shared values across deeply nested components.”
It removes the need for prop‑drilling—the messy situation where a value must be passed through many components that don’t even use it.
| ✅ Props are great for | ❌ Props fall short when |
|---|---|
| Parent‑to‑child communication | A value is needed by many deeply nested components |
| Simple, direct data flow | You are forced to pass the same prop five layers deep |
| Clear component contracts | Components become tightly coupled because of unnecessary prop passing |
When you encounter prop drilling, the code quickly becomes hard to manage—even in medium‑sized apps. The Context API solves this by allowing components to skip the chain and access shared values directly.
Typical use‑cases for Context
- Authentication / user data
- Theme (dark / light)
- Language preferences
- Shopping‑cart state
- App‑level settings
- UI states like modals or toasts
If the data must be accessed by multiple siblings, nested, or unrelated components, Context is the cleanest and most scalable approach.
How Context Works – The Four Steps
- Create a context
- Wrap your app (or part of it) with a provider
- Pass values to the provider
- Consume those values anywhere
Providers act like a data‑broadcasting station—any component listening to them can instantly receive the state.
Real‑World Example: Theme Toggle
You want to toggle light and dark mode, and multiple components need to know the current theme.
Step 1 – Create the Theme Context
// ThemeContext.tsx
import { createContext } from "react";
export const ThemeContext = createContext();
What’s happening?
createContext() creates a new Context object that will store and share theme‑related data across the app.
Step 2 – Build a Theme Provider
// ThemeProvider.tsx
import { useState } from "react";
import { ThemeContext } from "./ThemeContext";
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
const toggleTheme = () =>
setTheme(prev => (prev === "light" ? "dark" : "light"));
return (
{children}
);
};
Explanation
themestate lives here.toggleThemeupdates the theme.- The
valueprop exposes{ theme, toggleTheme }to all children.
Now any nested component can read the theme directly—no prop passing required.
Step 3 – Wrap Your App with the Provider
// App.jsx
import { ThemeProvider } from "./ThemeProvider";
import Home from "./Home";
export default function App() {
return (
);
}
All components inside “ now have access to the theme data.
Step 4 – Consume the Context Anywhere
// Home.jsx
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
export default function Home() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
## Current Theme: {theme}
Toggle Theme
);
}
What’s happening?
useContext(ThemeContext)pulls data directly from the provider.- No props, no drilling, no unnecessary pass‑throughs.
- Clean, direct, and easy to maintain.
Adding TypeScript for Safer Context
Step 1 – Define the Type
type ThemeContextType = {
theme: "light" | "dark";
toggleTheme: () => void;
};
Step 2 – Create a Typed Context
// ThemeContext.tsx
import { createContext } from "react";
export const ThemeContext = createContext(null);
Step 3 – Provide Typed Values
// ThemeProvider.tsx
import { useState, ReactNode, FC } from "react";
import { ThemeContext } from "./ThemeContext";
export const ThemeProvider: FC = ({ children }) => {
const [theme, setTheme] = useState("light");
const toggleTheme = () =>
setTheme(prev => (prev === "light" ? "dark" : "light"));
return (
{children}
);
};
Step 4 – Safely Consume the Context
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error("ThemeContext must be used under ThemeProvider");
const { theme, toggleTheme } = ctx;
Benefits
- Full type‑safety guarantees the shape of the context.
- Autocompletion and compile‑time checks prevent runtime errors.
When Not to Use Context
- For tiny, component‑local state.
- When simple parent‑to‑child communication suffices.
Props are still the best tool for straightforward data flow. Use Context only when state is needed by deep or unrelated components.
TL;DR
- Context API shares data across components without prop‑drilling.
- Ideal for global‑ish values: auth, theme, language, cart, UI state, etc.
- Implemented via createContext → Provider → value → useContext.
- TypeScript adds safety and better developer experience.
- Use it judiciously—don’t replace every piece of state with Context.
Mastering the Context API keeps React applications organized, reduces unnecessary prop passing, and simplifies maintenance—especially as projects grow. Happy coding!
Label and easier to work with.
Happy coding!