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 42 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Working with LocalStorage: Persisting React State Across Reloads

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.

ReactlocalStorageWeb APIsHooksPersistenceFrontend Developmentjavascriptfrontend

Previously in this course, we covered handling browser history. While that lesson focused on navigation, today we are tackling the "memory" of your application: how to keep data alive even after a user refreshes the page.

React state is volatile. Every time a user refreshes their browser, your application re-initializes, and your useState values reset to their defaults. If you want to remember a user's theme preference, a draft they were typing, or a list of items they interacted with, you need a way to store that data outside of React's memory. The browser's localStorage API is the standard tool for this persistence.

Understanding the localStorage API

localStorage is a simple key-value store built into every modern browser. It is synchronous, meaning it blocks the main thread while reading or writing, so we must use it carefully. Because it only stores strings, we have to serialize our data (using JSON.stringify) when saving it and deserialize it (using JSON.parse) when reading it back.

The primary methods you need are:

  • localStorage.setItem('key', 'value'): Stores data.
  • localStorage.getItem('key'): Retrieves data.
  • localStorage.removeItem('key'): Deletes a specific item.

Syncing State with localStorage

To make localStorage work with React, we need to bridge the gap between the browser's storage and our component's state. We do this by initializing state from storage and using useEffect to save changes whenever that state updates.

Consider a "Dark Mode" toggle for our movie browser. We want the user's choice to persist even if they close and reopen the tab.

JSX
import { useState, useEffect } from CE9178">'react';

function ThemeToggle() {
  // 1. Initialize state from localStorage
  const [isDarkMode, setIsDarkMode] = useState(() => {
    const savedTheme = localStorage.getItem(CE9178">'isDarkMode');
    return savedTheme ? JSON.parse(savedTheme) : false;
  });

  // 2. Sync state changes to localStorage
  useEffect(() => {
    localStorage.setItem(CE9178">'isDarkMode', JSON.stringify(isDarkMode));
  }, [isDarkMode]);

  return (
    <button onClick={() => setIsDarkMode(!isDarkMode)}>
      Switch to {isDarkMode ? CE9178">'Light' : CE9178">'Dark'} Mode
    </button>
  );
}

In this example, notice the "lazy initializer" function inside useState. By passing a function instead of a raw value, we ensure that localStorage.getItem only runs once during the initial mount, rather than on every single re-render. This is a crucial performance optimization for managing state.

Hands-on Exercise: Persisting User Preferences

Let's apply this to our movie project. In your existing movie browser, find the component that handles the search input.

  1. Create a localStorage key called 'movie-search-query'.
  2. Update your useState hook for the search term to initialize from that key.
  3. Add a useEffect hook that saves the search term to localStorage whenever the user types in the input.
  4. Verify the persistence by typing a search term, refreshing the page, and confirming the input still contains your text.

Common Pitfalls

Even for experienced engineers, localStorage has a few traps:

  • Blocking the Main Thread: Since localStorage is synchronous, don't use it for massive amounts of data (like a 50MB JSON blob). It will make your app feel stuttery.
  • The "Undefined" Trap: If localStorage.getItem returns null (because the key doesn't exist yet), JSON.parse(null) will return null. Always provide a fallback default value (e.g., savedTheme ? JSON.parse(savedTheme) : false).
  • Security: Never store sensitive information like passwords or auth tokens in localStorage. It is accessible by any script running on your page, making it vulnerable to Cross-Site Scripting (XSS) attacks.
  • React Reconciliation: Remember that updating state triggers React reconciliation, but localStorage is completely external to this process. Always keep your React state as the "source of truth."

Recap

Persistence is the final piece of the puzzle for a functional, user-friendly UI. We’ve learned that:

  1. localStorage is the browser's built-in key-value storage.
  2. We must always JSON.stringify and JSON.parse data since storage only accepts strings.
  3. Using a lazy initializer function in useState prevents expensive storage lookups on every render.
  4. useEffect is the perfect place to synchronize our React state with the browser's persistent storage.

By mastering this, you’ve ensured your users don't lose their progress when they navigate away or refresh. You're building apps that feel robust and thoughtful.

Up next: We will build a Favorites List, where we will use these persistence concepts to manage arrays of data.

Previous lessonHandling Browser HistoryNext lesson Building a Favorites List
Back to Blog

Similar Posts

ReactReactJune 25, 20263 min read

Building a Movie Filter Toggle in React: A Beginner's Guide

Master the art of UI state management by adding a filter toggle to your movie app. Learn to control list rendering using boolean state and checkbox inputs.

Read more
ReactReactJune 25, 2026

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 42 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min
3 min read

Fetching Data from an API: A Practical React Guide

Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.

Read more
ReactReactJune 25, 20264 min read

Rendering Lists of Data in React: A Practical Guide

Learn how to use the map method for list rendering in React. Master the key prop to keep your dynamic movie lists efficient, performant, and bug-free.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    3 min
  • 34

    Polishing the UI

    3 min
  • 35

    Finalizing the Movie Browser

    3 min
  • 36

    Review of Component Lifecycle

    4 min
  • 37

    Review of State Management

    4 min
  • 38

    Building a Modal Component

    3 min
  • 39

    Introduction to PropTypes

    3 min
  • 40

    Performance Optimization Basics

    3 min
  • 41

    Handling Browser History

    3 min
  • 42

    Working with LocalStorage

    3 min
  • 43

    Building a Favorites List

    3 min
  • 44

    Handling Media in React

    3 min
  • 45

    Introduction to Testing

    4 min
  • 46

    Debugging React Apps

    4 min
  • 47

    Deployment Basics

    3 min
  • 48

    Using External Libraries

    Coming soon
  • 49

    Advanced

    Coming soon
  • View full course