Learn to integrate custom hooks to manage dashboard settings. Discover how to use persistence to keep user theme preferences across page reloads in React.
Previously in this course, we explored the mechanics of building reusable abstractions in Introduction to Custom Hooks: Master Abstraction in React and implemented a robust storage utility in Building a useLocalStorage Hook: Persistence & State Management.
In this lesson, we are moving from theory to application. We will take our useLocalStorage hook and integrate it directly into our dashboard project. By the end of this session, your dashboard will remember user theme preferences even after a browser refresh, transforming your app from a transient state container into a persistent, user-aware interface.
In a production-grade dashboard, user experience is defined by continuity. If a user sets their interface to "Dark Mode" to save their eyes during a late-night session, they expect that preference to be there when they return the next morning.
Without persistence, your application state lives entirely in memory. Every time the user refreshes the page or navigates away and back, that state resets to the initial value. By leveraging the browser's localStorage API, we bridge the gap between the stateless nature of React and the user's desire for a consistent environment.
Let's look at a typical Settings component. Before refactoring, it likely uses standard useState, which is volatile.
JSX// Before: Volatile state import { useState } from CE9178">'react'; const Settings = () => { const [theme, setTheme] = useState(CE9178">'light'); return ( <div> <label> Theme: <select value={theme} onChange={(e) => setTheme(e.target.value)}> <option value="light">Light</option> <option value="dark">Dark</option> </select> </label> </div> ); };
To make this persistent, we swap useState for our custom useLocalStorage hook. If you haven't built the hook yet, review Building a useLocalStorage Hook: Persistence & State Management to ensure you have a version that handles JSON serialization and state synchronization.
JSX// After: Persistent state import { useLocalStorage } from CE9178">'../hooks/useLocalStorage'; const Settings = () => { // We use our custom hook just like useState const [theme, setTheme] = useLocalStorage(CE9178">'dashboard-theme', CE9178">'light'); return ( <div className="settings-panel"> <h2>Preferences</h2> <label htmlFor="theme-select">Interface Theme:</label> <select id="theme-select" value={theme} onChange={(e) => setTheme(e.target.value)} > <option value="light">Light</option> <option value="dark">Dark</option> </select> <p>Current theme stored: {theme}</p> </div> ); };
By changing one line of code, we've offloaded the responsibility of synchronization to our custom hook. The component remains clean, declarative, and focused solely on UI rendering.
Now it is your turn to apply this to our running project. Follow these steps to persist your dashboard's sidebar collapse state:
Sidebar component.useState to track whether the sidebar is collapsed or expanded, replace it with useLocalStorage('sidebar-collapsed', false).sidebar-collapsed key is present in localStorage.Even with a robust hook, there are traps that catch many intermediate developers:
localStorage only stores strings. If you try to store an object or array without JSON.stringify, you'll end up with [object Object] in your storage. Ensure your useLocalStorage hook handles this conversion internally.localStorage. Use it only for UI preferences and non-sensitive view settings.By refactoring your dashboard settings, you’ve moved beyond simple React state into building features that feel "real" to the user. We’ve successfully:
useState with a persistent useLocalStorage hook.Persistence is a foundational pillar of high-quality web applications. You now have the tools to ensure your dashboard respects the user's choices across their entire session lifecycle.
Up next: We will tackle more complex state patterns by learning to manage multiple state transitions in a single, predictable flow with useReducer.
Learn to build a robust useLocalStorage hook. Master generic storage, JSON serialization, and cross-tab synchronization to keep your React app state persistent.
Read moreLearn to use localStorage to persist your React app's state across browser refreshes. Master the art of syncing local data with your component state.
Refactoring Dashboard Settings
Structuring State for Performance
Handling Authentication State
Integrating Reducers with Auth State
Introduction to React Router
Dynamic Routing with URL Parameters
Nested Routes and Layouts
Protected Routes for Authenticated Views
Programmatic Navigation
Building the Dashboard Navigation Structure
Asynchronous Data Lifecycle
Caching Strategies with React Query
Mutations and Data Updates
Synchronizing Client and Server State
Integrating Live Data into the Dashboard
Error Handling and Loading UI
Controlled vs Uncontrolled Components
Real-time Form Validation
Schema-based Validation with Zod
Handling Multi-step Forms
Optimizing Form Submissions
Performance Profiling with React DevTools
Refactoring for Scalability
Finalizing Dashboard Data Flow
Deploying the Application
Advanced Hook Composition
Implementing Middleware for State
Advanced Context Patterns
Router Loaders and Data Prefetching
Complex Route Guards
Handling Large Datasets in UI
Testing Hooks and Components
Managing Global Modals
Implementing Keyboard Shortcuts
Optimizing Asset Loading
Internationalization Basics
Managing WebSocket Connections