February 13, 2023

. 4 min read

Using LocalStorage with React

Learn how to use Browser Local Storage to save and retrieve state data in React easily.

––– views

When building web applications with React, we may want to persist some data, so they are available when we revisit the application.

This lesson will discuss how to persist a React state in the localStorage. We’ll use the storage mechanism in our todos project to store and retrieve the todos state that renders the UI.

The Web Storage API

For every website or web app we render in the browser, the browser creates a storage unit for them to store data. It also provides storage access for developers to interact with the data.

Local Storage and Session Storage

We can use either the localStorage API or sessionStorage API to store data in the browser's storage.

The sessionStorage, as the name implies, lets us store data that persist throughout a session. In other words, it lasts as long as the current browser tab remains active. Meanwhile, data stored in the localStorage has no expiration date. The data is available when the browser is closed and shared between windows that use the same origin.

Same origin implies same domain, same protocol(HTTP/HTTPS), and same port. URL path can be different.

In our todos project, we want the todos state data to persist across the same origin and not be bound to the current browser tab. So, we will use the localStorage. The procedure, however, is similar to implementing the sessionStorage.

Using the localStorage

If we open the console of any web browser and type/enter localStorage, we’ll have access to the Storage object of the page. Inside this object, we have access to the storage space.

localStorage
// same as this:
window.localStorage

The window object is global; we can access its built-in properties without a window. prefix.

If we go further and look at the methods available on the prototype, we’ll see helpful methods like setItem, getItem, removeItem, and clear. We’ll discuss each of them, starting with the setItem.

Saving Data With setItem

The localStorage setItem() lets us add items to the Storage object. It takes two arguments, namely, key and value:

localStorage.setItem("key", "value")

The key is the unique name we give to the value to store.

To see how it works, let’s open the browser’s console and paste the following code:

localStorage.setItem("todos", "data")

Once we press enter, we can open the browser “Local Storage” area and see the data.

If you are on:

  • Mozilla Firefox: Open DevTools, Storage → Local Storage
  • Chrome: Open DevTools, Application → Local Storage

Then, find the current site URL to see the set item.

The storage only accepts strings for both keys and values. It automatically converts data types like Number and Boolean to String. If we send an object data type to the localStorage, we’ll use JSON.stringify() method to convert the JavaScript object to a JSON string.

Reading Data From Local Storage With getItem

To get an item from local storage, we’ll call the getItem() method and pass the item’s key to retrieve it as an argument. The syntax looks like so:

localStorage.getItem("key")

If we want to retrieve the earlier data we set in the local storage, we can pass the todos key like so in the console:

localStorage.getItem("todos")

Saving and Reading JavaScript object

Let’s see how to work with a JavaScript object. Open the browser console and add the following object:

const obj = {
  id: 1,
  title: "Setup development environment",
  completed: true,
}

Hit enter and add the following line:

localStorage.setItem("myItem", JSON.stringify(obj))

The code would save the obj data in the “Local Storage”. The JSON.stringify(obj) used in the line above helps convert the JavaScript object into a JSON string that the storage can handle.

To read the data using getItem(), let’s add the following code in the console:

localStorage.getItem("myItem")

We’ll receive the data in JSON format like so:

'{"id":1,"title":"Setup development environment","completed":true}'

This is so because the storage always returns a string.

Use **JSON.parse()** to Convert to JavaScript Object

The JSON.parse() method will parse the JSON string and returns a JavaScript object. If we enter the following code in the console, we’ll get a proper JavaScript object:

JSON.parse(localStorage.getItem("myItem"))

Removing Data From Local Storage with removeItem

The localStorage removeItem() method lets us remove an item from the storage. It takes the item’s key to remove as an argument. The syntax looks like so:

localStorage.removeItem("key")

To remove the item that we saved earlier from the storage, we will call the method with the key like so:

localStorage.removeItem("myItem")

Clearing the Storage With localStorage clear

We can clear the storage instead of removing items with their keys. To remove all stored data from the “Local Storage”, we’ll use the following code:

localStorage.clear()

Persisting Todos Data to Browser Storage

Now that we know how the localStorage works, we’ll use the setItem() and getItem() methods to save and retrieve the todos state to/from the storage.

Saving Todos State in Local Storage

In the React Hooks lesson, we mentioned that any action that modifies a state outside a component scope is a side effect and must isolate inside a useEffect Hook.

Since we’ll perform an action that modifies the browser storage, the logic will go inside this Hook. Let’s open the components/TodosLogic.jsx file, import a useEffect Hook, and invoke a setItem method in the Hook:

import { useState, useEffect } from 'react';
// ...
const TodosLogic = () => {
  const [todos, setTodos] = useState([
    // ...
  ]);
  // ...
  useEffect(() => {
    // storing todos items
    const temp = JSON.stringify(todos);
    localStorage.setItem('todos', temp);
  }, [todos]);

  return (
    // ...
  );
};
export default TodosLogic;

The useEffect Hook containing the storage logic will run when the component renders and rerun whenever the todos dependency updates. So whenever the todos state update, the Hook will rerun the effect to save the updated data in the “Local storage”.

If we save the file and open the browser’s local storage, we should see the todos items.

Retrieving the Todos Items From Local Storage

To retrieve and display the storage items, we’ll create a function that returns the items and use the function as the initial value of the state.

Still, in the TodosLogic component, we’ll add this function:

function getInitialTodos() {
  // getting stored items
  const temp = localStorage.getItem('todos');
  const savedTodos = JSON.parse(temp);
  return savedTodos || [];
}

After that, we’ll find the following state:

const [todos, setTodos] = useState([
  // ...
]);

And initial the state variable with the getInitialTodos function:

const [todos, setTodos] = useState(getInitialTodos());

The TodosLogic component should look like so:

const TodosLogic = () => {

  const [todos, setTodos] = useState(getInitialTodos());

  function getInitialTodos() {
    // getting stored items
    const temp = localStorage.getItem('todos');
    const savedTodos = JSON.parse(temp);
    return savedTodos || [];
  }

  useEffect(() => {
    // storing todos items
    const temp = JSON.stringify(todos);
    localStorage.setItem('todos', temp);
  }, [todos]);

  // handlers here...

  return (
    // ...
  );
};
export default TodosLogic;

Notice we no longer use static todos data. The component will use the current items saved in the local storage as the initial state.

If we save the file and interact with the todos application, the items should persist and be available when we refresh the page and on a subsequent visit.

Following the same procedure above, we can persist the form's input values, theme values for dark/light mode, etc. Using the web storage for our use case and the one we just mentioned is okay. However, storing more significant amounts of data is better with the IndexedDB.

In the next lesson, we will discuss using SVG icons in React.

Next part: How to Use React Icons

continue

share

Discussion