Skip to main content

Building a Theme Switcher with Context (Part 1): A Practical Example #100

📖 Introduction

Following our discussion on when to use the Context API, this article provides a complete, practical example of one of its most common use cases: building a theme switcher. We will walk through the process of creating a theme context, providing it to our application, and consuming it to toggle between a light and dark mode.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • The core concepts of the Context API.
  • Basic CSS.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • Creating a Theme Provider Component: How to create a dedicated component to manage and provide the theme state.
  • Consuming the Theme Context: How to use the theme context to style components.
  • Building a Complete Theme Switcher: A step-by-step guide to building a fully functional theme switcher.

🧠 Section 1: The Core Concepts of a Context-Based Theme Switcher

A theme switcher is a perfect example of a feature that benefits from the Context API. The theme is a global concern that can affect any component in the application. By using the Context API, we can provide the current theme and a function to update it to any component that needs it, without having to pass props down through the entire component tree.

We will create a ThemeProvider component that will be responsible for:

  1. Managing the current theme state ('light' or 'dark').
  2. Providing a function to toggle the theme.
  3. Making the theme and the toggle function available to all of its children via the context provider.

💻 Section 2: Deep Dive - Implementation and Walkthrough

Let's build our theme switcher.

2.1 - The ThemeProvider

First, let's create a ThemeProvider.js file. This component will encapsulate all of our theme-related logic.

// ThemeProvider.js
import React, { useState, createContext } from 'react';

export const ThemeContext = createContext();

export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');

const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}

2.2 - The App.js File

Now, let's wrap our application with the ThemeProvider in App.js. We'll also create a simple layout that consumes the theme.

// App.js
import React, { useContext } from 'react';
import { ThemeProvider, ThemeContext } from './ThemeProvider';
import './App.css';

function AppContent() {
const { theme, toggleTheme } = useContext(ThemeContext);

return (
<div className={`App ${theme}`}>
<h1>Current Theme: {theme}</h1>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}

function App() {
return (
<ThemeProvider>
<AppContent />
</ThemeProvider>
);
}

export default App;

2.3 - The CSS

Finally, let's add some simple CSS to our App.css file to style the themes.

/* App.css */
.App {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
transition: background-color 0.3s, color 0.3s;
}

.light {
background-color: #fff;
color: #333;
}

.dark {
background-color: #333;
color: #fff;
}

Now, when you run your application, you will have a fully functional theme switcher.


💡 Conclusion & Key Takeaways

In this article, we've built a complete, practical example of a theme switcher using the Context API. We've seen how to create a dedicated provider component to manage our theme state and how to consume that state in our application.

Let's summarize the key takeaways:

  • The Context API is a powerful tool for managing global state like themes.
  • Creating a dedicated provider component is a great way to encapsulate your context-related logic.
  • By combining the Context API with CSS, you can create dynamic and responsive user interfaces.

Challenge Yourself: To solidify your understanding, try to add a third theme to the theme switcher (e.g., a "sepia" theme).


➡️ Next Steps

You now have a solid understanding of how to build a practical feature with the Context API. In the next article, "Building a Theme Switcher with Context (Part 2)", we will explore how to add more features to our theme switcher, such as persisting the theme to local storage.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • Theme: A set of styles that define the look and feel of an application.
  • Provider Component: A component that provides a value to a context.

Further Reading