By Hemanta Sundaray on 2021-07-06
localStorage is a Web Storage API, using which browsers are able to save data in the form of key/value pairs.
localStorage stores data with no expiration date.
The data is persisted even when the browser is closed and reopened.
The localStorage API can only save strings.
Inside a React component, we should place our call to localStorage inside useEffect because of performance reasons. localStorage is a synchronous API; therefore, using it outside of useEffect can slow down our application.
We can save a key/value pair to localStorage using the following syntax:
localStorage.setItem("key", "value");
import React, { useState, useEffect } from "react"
function App() {
const [nums, setNums] = useState([1, 2, 4])
useEffect(() => {
localStorage.setItem("nums", JSON.stringify(nums))
}, [nums])
function handleAddClick() {
setNums([...nums, Math.random()])
}
return (
<button className="btn btn-primary m-5" onClick={handleAddClick}>
Add Random Number
</button>
)
}
export default App
Because localStorage can ONLY save strings, we must convert arrays/objects to strings before saving them to localStorage.
We can convert an array/object to a string using JSON.stringify().
In the code snippet above, on line 7, we convert the nums array to a string using JSON.stringify() before saving it to the localStorage.
Every time we click the AddRandomNumber button, we add a random number to the nums array, which runs useEffect (the nums state variable is added to the dependency array), thereby persisting the updated nums array to localStorage.
We can read the value stored in localStorage using the following syntax:
localStorage.getItem("key");
localStorage always gives us a string, so we need to manually convert it to a Number.
let value = localStorage.getItem("key")
value = Number.parseInt(value, 10)
Booleans could be either true or false. When saved to localStorage, they will either be "true" or "false", because they get converted to strings.
Therefore, the easiest way to convert those strings back to booleans is to always compare the localStorage entry to the string "true".
const value = localStorage.getItem("key") === "true"
Remember that we convert arrays and objects to strings using JSON.stringify() before saving them to localStorage. This means that when we want to restore them, we need to parse them into objects using JSON.parse().
const value = JSON.parse(localStorage.getItem("key"))
We can hydrate the initial state with data stored in localStorage using the following approach:
import React, { useState } from "react"
const App = () => {
// do NOT use this (for performance reasons)
const [state, setState] = useState(localStorage.getItem("key"))
return null
}
The code above works but creates a performance issue: we only need the initial state once; however, every time the App component rerenders, we will end up running localStorage.getItem("key").
To fix the issue, we need to pass a function definition that will allow React to call it only on the initial render.
Here is how it looks like:
import React, { useState } from "react"
const App = () => {
const [state, setState] = useState(() => localStorage.getItem("key"))
return null
}