# Step-by-Step Guide to Light/Dark Theme Toggle with React Context API

» In modern React applications, **state management** plays a crucial role. As applications grow larger, **prop drilling** (passing props down multiple levels) becomes a nightmare. This is where the **React Context API** shines — it provides a clean and powerful way to share state across components without unnecessary prop drilling.

» In this article, we will dive deep into the **Context API** with an easy-to-understand **Light/Dark Theme Toggle** example. Along the way, we’ll explore how it works, why it’s useful, and best practices you can apply in real-world projects.

## 🔹 What is the Context API?

The **Context API** is a built-in feature in React that allows you to **create global state** accessible by any component in the component tree, without passing props manually at every level.

* Think of Context as a **“global store”** for React components.
    
* It allows **data sharing** across deeply nested components.
    
* It’s a great alternative for simpler use cases where using heavy libraries like **Redux** or **Zustand** might be overkill.
    

## 🔹 Steps to Use Context API

There are 3 main steps:

1. **Create a Context** using `createContext()`.
    
2. **Provide the Context** using `Context.Provider`.
    
3. **Consume the Context** using `useContext()`.
    

Let’s break it down with the Theme Toggle example.

🔹 Step 1: Creating the Context & Provider

```javascript
import React, { createContext, useState } from 'react'

// Step 1: Create Context
export let ThemeContext = createContext('')

const ThemeProvider = ({children}) => {
  let [theme, setTheme] = useState('light')

  // Step 2: Define logic to toggle theme
  let handleTheme = () => {
    setTheme((theme) => theme === "light" ? "dark" : "light")
  }

  return (
    // Step 3: Provide the context value
    <ThemeContext.Provider value={{ theme, handleTheme }}>
      {children}
    </ThemeContext.Provider>
  )
}

export default ThemeProvider
```

Here’s what’s happening:

* `ThemeContext` is created using `createContext()`.
    
* `ThemeProvider` is a **wrapper component** that manages the `theme` state and provides it to all children components.
    
* The `value` prop of `ThemeContext.Provider` contains both `theme` and the `handleTheme` function.
    

🔹 Step 2: Wrapping the App with Provider

```javascript
import React from 'react'
import ThemeProvider from './ThemeProvider'
import Home from './Home'
import Profile from './Profile'

const App = () => {
  return (
    <ThemeProvider>
      <Home />
      <Profile />
    </ThemeProvider>
  )
}

export default App
```

Here we wrap `<Home/>` , `<Profile/>` with `<ThemeProvider>`.  
This means **all components inside ThemeProvider can now access** `theme` and `handleTheme` directly.

Step 3: Consuming the Context

```javascript
import React, { useContext } from 'react'
import { ThemeContext } from './ThemeProvider'

const Profile = () => {
  let { theme } = useContext(ThemeContext)

  let styles = {
    background: theme === "light" ? "#f0f0f0" : "#444",
    color: theme === "light" ? "#111" : "#eee",
    padding: "30px",
    textAlign: "center",
    borderRadius: "10px",
    marginTop: "20px"
  }

  return (
    <div style={styles}>
      <h2>Profile Section</h2>
      <p>This section also follows the <b>{theme.toUpperCase()} MODE</b>.</p>
    </div>
  )
}

export default Profile
```

```javascript
import React, { useContext } from 'react'
import { ThemeContext } from './ThemeProvider'

const Home = () => {
  let { theme, handleTheme } = useContext(ThemeContext)

  let styles = {
    background: theme === "light" ? "#fff" : "#333",
    color: theme === "light" ? "#333" : "#fff",
    padding: "50px",
    textAlign: "center"
  }

  return (
    <div style={styles}>
      <h1>{theme.toUpperCase()} MODE</h1>
      <button onClick={handleTheme}>Toggle Theme</button>
    </div>
  )
}

export default Home
```

* `useContext(ThemeContext)` is used to **consume** the context.
    
* Now, `theme` and `handleTheme` are available inside the `Home` and `profile` component.
    
* The UI dynamically switches between **Light Mode** and **Dark Mode** when the button is clicked.
    

## 🔹 Benefits of Using Context API

✅ **No more prop drilling** – Pass data once at the top and consume it anywhere.  
✅ **Simple state management** – Great for small to medium-scale apps.  
✅ **Improves maintainability** – Your code is cleaner, modular, and reusable.  
✅ **Performance friendly** – React ensures only the necessary components re-render.

## 🔹 When to Use Context API?

* When **global state** is required across multiple components (e.g., theme, authentication, language preference).
    
* When you want to **avoid Redux/other state libraries** for small projects.
    
* When **data sharing** between non-parent-child components is necessary.
    

⚠️ **Caution:** Don’t overuse Context API for everything. For large-scale applications with complex business logic, **Redux Toolkit, Zustand, or Recoil** might be better choices.

## 🔹 Final Thoughts

The **React Context API** is a game-changer for state management when used correctly. Our **Theme Toggle** example is simple, yet powerful enough to demonstrate how Context helps us manage shared state.

If you’re building a **real-world application**, consider combining Context with other tools (like custom hooks, reducers, or middleware) for even greater flexibility.

By mastering Context API, you’ll take one more step toward becoming a **pro-level React developer**.
