Saving Redux State to Local Storage

This video is available to view for members only.

Click here to Join!

Already a member?


In this video we are going to look at problem that is inherent in any Redux project, which is that by default, your application's state will not persist past a browser refresh.

To remedy this, we will save our application's local representation of state to localStorage.

By using localStorage, our locally saved state will survive even if the browser window is closed. If you'd rather only keep data alive as long as the browser window is kept open then sessionStorage may be the way to go. The API is identical.

This is a tip I learned from this excellent video from Dan Abramov.

With the way in which this works, you could adapt the following two functions to any sort of storage you like. For every similar problem I've ever had, localStorage has been perfectly fine.

localStorage acts a key / value store. This means we need a key, and a value to write. And a key to read.

You won't need to do any import statements to make this work.

Let's see the code:

// /src/connectivity/localStorage.js

export const loadState = () => {
  try {
    const serializedState = localStorage.getItem('state');

    if (serializedState === null) {
      return undefined;

    return JSON.parse(serializedState);

  } catch (err) {
    return undefined;

export const saveState = (state) => {
  try {
    const serializedState = JSON.stringify(state);
    localStorage.setItem('state', serializedState);
  } catch (err) {
    // die

As our state is a plain old JavaScript object, we can serialize (JSON.stringify) and deserialize it (JSON.parse) as required.

By subscribing the saveState functionality to our Redux store, we can ensure this function will be called any time our state is updated. It's a lovely, clean separation of concerns.


  store.subscribe(() => {
      auth: store.getState().auth

However, as our application's state may be changing frequently, we likely don't need to write every single change to localStorage, which would be costly.

By wrapping the function in lodash's throttle we can ensure this method will be called at most, once per second (1000 ms) in our example:


import _ from 'lodash';

// * snip *

  store.subscribe(_.throttle(() => {
      auth: store.getState().auth
  }, 1000));


Code For This Course

Get the code for this course.

Code For This Episode

Get the code for this episode.

Share This Episode

If you have found this video helpful, please consider sharing. I really appreciate it.

Episodes in this series

# Title Duration
1 App Walkthrough - User Experience 03:15
2 App Walkthrough - Developer Experience 07:41
3 Development Environment Setup 06:34
4 Login - Part 1 09:15
5 Login - Part 2 07:55
6 Login - Part 3 12:37
7 Login - Part 4 10:22
8 Login - Part 5 08:00
9 Saving Redux State to Local Storage 08:50
10 Logout 10:57
11 Adding an Auth-aware NavBar 14:43
12 Cleanup, Linting, and Login Form Styling 09:58
13 Showing Spinning Icons, Because Why Not? 08:11
14 More Robust Request Tracking 09:07
15 Getting Started Testing With Jest 06:43
16 Testing Request Reducer - Part 1 11:35
17 Testing Request Reducer - Part 2 05:25
18 Testing AuthSaga - Happy Path 09:19
19 Testing AuthSaga - Unhappy Paths 04:38
21 Testing JavaScript's Fetch with Jest - Happy Path 05:15
21 Testing JavaScript's Fetch with Jest - Unhappy Paths 04:35
22 Getting Started with Jest Mocks 08:52
23 Using Webpack Environment Variables in Jest Tests 09:37
24 User Profile Page - Part 1 07:31
25 User Profile Page - Part 2 10:25
26 User Profile Page - Part 3 07:23
28 Change Password - Part 2 07:59