Persisting tasks in the local storage [part-4 ]

Persisting tasks in the local storage [part-4 ]

Β·

4 min read

This article is a continuation of our todo web app.

Check out part-3

Now that we have learned how to create a functional todo web app, we should move on to persist our data to the local storage using the localStorage API.

So that every time a user adds a task, the task is saved in the local storage.

Since we will need to monitor our state changes, will also use the useEffect hook.

In App.jsx first import useEffect

import { useState, useEffect } from 'react'
import { v4 as uniqueId } from 'uuid'
import { TrashIcon } from '@heroicons/react/24/solid'

Then add this code (above the return).

  useEffect(() => {
    localStorage.setItem('tasks', JSON.stringify(tasks))
  }, [tasks])

Note: You could add the code anywhere as long as it is below the tasks state and above the return statement.

Here, the useEffect hook monitors our tasks state, if there is a change, the code inside the useEffect runs.

Note: We passed tasks as our dependency array [tasks] that's what the useEffect will monitor.

Whenever our tasks state changes, the local storage in the browser is updated.

First, we get access to the local storage with localStorage then we use the setItem method to store data in the browser's localStorage object.

In setItem, the first argument 'tasks' is the key that we will use to retrieve the data later, and the second argument is the value (our actual data) of the key, which must be a string.

And because the local storage can only store string values, the second argument in setItem must be a string, we convert tasks array to a JSON string using JSON.stringify, so that it can be stored as a string in localStorage. Don't overthink too much, the whole array is just converted to one big string, simple!

We are done setting up our local storage.

Back to our app in the browser, add some tasks.

In your browser devtools, go to Application (some browsers use storage).

Then on the left side toggle(click) Local Storage. You'll see http://localhost:5173/ click it.

You should see (sometimes you'll need to click the task) πŸ‘‡

Data stored in local storage will persist( remain there) even if you close the browser or shut down your device.

Modern smartphones and tablets have support for the localStorage API in their web browsers.

Now that our local storage is working, we should be able to use the value stored in the local storage to update our state.

At the moment, this is what our state looks like.

const [tasks, setTasks] = useState([])

Instead of initializing our tasks to an empty array, we want to assign the data in the local storage to our tasks.

 const [tasks, setTasks] = useState(
    JSON.parse(localStorage.getItem('tasks'))
  )

Remember the key we set when storing data in the local storage?

Now using the method getItem we pass the key 'tasks'. The local storage could be holding other data. That's why we use the key to get specific info from the local storage API. The key itself is not returned, it is used as an identifier.

In the local storage, our data was stored as a string array of objects.

We used JSON.parse to convert the string array back to an array that we can now iterate over in our app.

Let's go back to the browser and try reloading the application.

The tasks should persist.

BonusπŸ’°πŸ’°

In case you are building an app and you don't want to have errors when getting data from the local storage because of maybe the data being null or undefined.

You can set a default value.

Our app will still work even if you don't set a default value. This is because earlier in handleSubmit, we made sure an empty task can not be used to update the state.

Now, this is how you set a default value.

 const [tasks, setTasks] = useState(
    JSON.parse(localStorage.getItem('tasks')) ?? []
  )

Here, if the parsing operation fails (i.e., the retrieved value is not valid JSON), or if the parsed value is null or undefined, the default value will be an empty array []

The nullish coalescing operator ?? is a logical operator in JavaScript that is used to provide a default value when a variable is null or undefined

Finally. The client side of our web app is done.

Congratulations on making it this far.πŸ‘πŸ‘πŸ‘

Assignment: For your benefit, research the difference between JSON and json

Next up in part-5, we'll create a backend with nodejs and express the store our tasks in mongodb.

Β