Managing global state is an essential feature in many applications. It is commonly used for tasks like handling user login data or controlling the app’s theme.
Additionally, persisting state across page refreshes is crucial to ensure a consistent user experience.
In this article, I’ll demonstrate a simple approach to achieving global and persistent state management using the Context API, with a practical example of theme control.
Roadmap
Step 1: Create ThemeContext.tsx
In this file, we create the ThemeContext to manage theme-related state globally. We also define a custom hook, useThemeContext, to simplify access to the context in components.
import { createContext, useContext } from "react";
// Define context type
interface ThemeContextType {
isDarkMode: boolean;
toggleTheme: () => void;
}
// Create context
export const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
// Create custom hook to access
export const useThemeContext = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
};
Step 2: Create ThemeProvider.tsx
The ThemeProvider component provides the ThemeContext to its children and handles theme state changes.
import React, { useState } from "react";
import { ThemeContext } from "./ThemeContext";
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [isDarkMode, setIsDarkMode] = useState(false);
const toggleTheme = () => {
const newTheme = !isDarkMode ? "dark" : "light";
// Change state value
setIsDarkMode(!isDarkMode);
// Save value to local storage
// Toggle "dark" class in html element
localStorage.setItem("theme", newTheme);
document.documentElement.classList.toggle("dark", !isDarkMode);
};
return (
<ThemeContext.Provider value={{ isDarkMode, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
Step 3: Wrap App in the ThemeProvider
Finally, wrap the App component with the ThemeProvider in main.tsx to enable context usage throughout the application.
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import { ThemeProvider } from './context/ThemeProvider.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</StrictMode>,
)
Step 4: Access Context Values in Components
With the context set up, you can now access the theme values and toggle function in your components.
import { useThemeContext } from '@/context/ThemeContext';
function App() {
const { isDarkMode, toggleTheme } = useThemeContext();
return (
<div>
<p>isdarkMode: {isDarkMode}</p>
<button onclick={toggleTheme}>Toggle Theme</button>
</div>
)
}
export default App
Conclusion
This approach demonstrates how to manage global and persistent state using the Context API. You can now adapt this method for other use cases like user authentication or language settings.
Top comments (0)