Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 7 of the Intermediate React: Hooks, State & Data Patterns course
ReactJune 25, 20264 min read

Refactoring Dashboard Settings: Persistence with React Hooks

Learn to integrate custom hooks to manage dashboard settings. Discover how to use persistence to keep user theme preferences across page reloads in React.

ReactHooksPersistenceDashboardRefactoringFrontendjavascript

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.

Why Persistence Matters for Your Dashboard

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.

Integrating the Hook: A Practical Refactor

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.

Hands-on Exercise: Syncing the Dashboard Layout

Now it is your turn to apply this to our running project. Follow these steps to persist your dashboard's sidebar collapse state:

  1. Locate your Sidebar component.
  2. If you are currently using useState to track whether the sidebar is collapsed or expanded, replace it with useLocalStorage('sidebar-collapsed', false).
  3. Verify that when you refresh the browser while the sidebar is collapsed, it remains collapsed upon reload.
  4. Open the browser's Application tab in DevTools to confirm the sidebar-collapsed key is present in localStorage.

Common Pitfalls in State Persistence

Even with a robust hook, there are traps that catch many intermediate developers:

  • JSON Serialization Errors: 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.
  • The "Flash" of Default State: If your initialization logic is slow, the UI might render the default value before the hook reads from storage. Keep your initial value logic synchronous and performant.
  • Over-persistence: Do not store everything. Large datasets or sensitive information (like unencrypted auth tokens) should not live in localStorage. Use it only for UI preferences and non-sensitive view settings.
  • Stale Data: If you change the shape of your stored data (e.g., renaming a property), older browsers might still have the old format in their storage. Always write your code to handle potential schema mismatches gracefully.

Recap

By refactoring your dashboard settings, you’ve moved beyond simple React state into building features that feel "real" to the user. We’ve successfully:

  1. Replaced volatile useState with a persistent useLocalStorage hook.
  2. Maintained clean component logic by keeping the storage complexity hidden.
  3. Ensured that user preferences survive browser reloads.

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.

Previous lessonBuilding a useLocalStorage HookNext lesson Complex State with useReducer
Back to Blog

Similar Posts

ReactState ManagementJune 25, 20264 min read

Building a useLocalStorage Hook: Persistence & State Management

Learn to build a robust useLocalStorage hook. Master generic storage, JSON serialization, and cross-tab synchronization to keep your React app state persistent.

Read more
ReactJune 25, 20263 min read

Working with LocalStorage: Persisting React State Across Reloads

Part of the course

Intermediate React: Hooks, State & Data Patterns

intermediate · Lesson 7 of 48

  1. 1

    Mastering useRef for DOM Access

    4 min
  2. 2

    Persistent Mutable Values with useRef

    4 min
  3. 3

    Memoizing Expensive Calculations with useMemo

    3 min

Learn to use localStorage to persist your React app's state across browser refreshes. Master the art of syncing local data with your component state.

Read more
ReactJune 25, 20264 min read

Implementing Theme Context: A Global Toggle for React Dashboards

Learn to build a production-ready theme system using the Context API and useReducer. Master global state for light/dark mode in your React dashboard.

Read more
4

Optimizing Function References with useCallback

3 min
  • 5

    Introduction to Custom Hooks

    4 min
  • 6

    Building a useLocalStorage Hook

    4 min
  • 7

    Refactoring Dashboard Settings

    4 min
  • 8

    Complex State with useReducer

    3 min
  • 9

    Managing Object-Based State

    3 min
  • 10

    Introduction to Context API

    3 min
  • 11

    Architecting Global State with Context and Reducer

    3 min
  • 12

    Implementing Theme Context

    4 min
  • 13

    Structuring State for Performance

    Coming soon
  • 14

    Handling Authentication State

    Coming soon
  • 15

    Integrating Reducers with Auth State

    Coming soon
  • 16

    Introduction to React Router

    Coming soon
  • 17

    Dynamic Routing with URL Parameters

    Coming soon
  • 18

    Nested Routes and Layouts

    Coming soon
  • 19

    Protected Routes for Authenticated Views

    Coming soon
  • 20

    Programmatic Navigation

    Coming soon
  • 21

    Building the Dashboard Navigation Structure

    Coming soon
  • 22

    Asynchronous Data Lifecycle

    Coming soon
  • 23

    Caching Strategies with React Query

    Coming soon
  • 24

    Mutations and Data Updates

    Coming soon
  • 25

    Synchronizing Client and Server State

    Coming soon
  • 26

    Integrating Live Data into the Dashboard

    Coming soon
  • 27

    Error Handling and Loading UI

    Coming soon
  • 28

    Controlled vs Uncontrolled Components

    Coming soon
  • 29

    Real-time Form Validation

    Coming soon
  • 30

    Schema-based Validation with Zod

    Coming soon
  • 31

    Handling Multi-step Forms

    Coming soon
  • 32

    Optimizing Form Submissions

    Coming soon
  • 33

    Performance Profiling with React DevTools

    Coming soon
  • 34

    Refactoring for Scalability

    Coming soon
  • 35

    Finalizing Dashboard Data Flow

    Coming soon
  • 36

    Deploying the Application

    Coming soon
  • 37

    Advanced Hook Composition

    Coming soon
  • 38

    Implementing Middleware for State

    Coming soon
  • 39

    Advanced Context Patterns

    Coming soon
  • 40

    Router Loaders and Data Prefetching

    Coming soon
  • 41

    Complex Route Guards

    Coming soon
  • 42

    Handling Large Datasets in UI

    Coming soon
  • 43

    Testing Hooks and Components

    Coming soon
  • 44

    Managing Global Modals

    Coming soon
  • 45

    Implementing Keyboard Shortcuts

    Coming soon
  • 46

    Optimizing Asset Loading

    Coming soon
  • 47

    Internationalization Basics

    Coming soon
  • 48

    Managing WebSocket Connections

    Coming soon
  • View full course