Synchronize React State Across Multiple Tabs

Simant Thapa Magar
readytowork, Inc.
Published in
2 min readOct 21, 2022

State in react is simply an object that holds information about the component and controls the rendering. A lot of component logic is based on state’s value. However that is limited to single tab because state by default isn’t synchronized across multiple tabs. There comes cases where we would like the state to be maintained across all tabs as users behavior can’t be predicted. Some example of such cases may be maintaining shopping cart for an e-commerce store or maintaining username on site’s header and so on. On this article we will be implementing a simple trick to synchronize state across multiple tabs using local storage.

Overflow

The overflow of the process is very simple. Whenever we are to update state of the component, we will be storing it in local storage in addition to actual state update. We will add an event listener that gets invoked when there’s an update to local storage. The event listener will be responsible for updating the state and hence maintain the state across all active tabs.

Example Component

Using the effect hook to initialize event listener for storage as well as setting initial state if there’s an existing data on local storage.

useEffect(() => {
// handler function for storage event
const onStorageUpdate = (e) => {
const { key, newValue } = e;
if (key === "name") setName(newValue)
}

// event listener for storage event
window.addEventListener('storage', onStorageUpdate)
// checking initial value
const nameFromLocalStorage = localStorage.getItem("name")
if(nameFromLocalStorage) setName(nameFromLocalStorage)
return () => {
window.removeEventListener('storage',onStorageUpdate)
}
}, [])

Next we just need to update state as well as update local storage when handling change

const handleNameChange = (e) => {
setName(e.target.value)
localStorage.setItem("name",e.target.value)
}

Full Component

import React, { useEffect, useState } from 'react';function Name() {
const [name,setName] = useState('')
useEffect(() => {
const onStorageUpdate = (e) => {
const { key, newValue } = e;
if (key==="name") setName(newValue)
}
window.addEventListener('storage', onStorageUpdate)
const nameFromLocalStorage = localStorage.getItem("name")
if(nameFromLocalStorage) setName(nameFromLocalStorage)
return () => {
window.removeEventListener('storage',onStorageUpdate)
}
}, [])

const handleNameChange = (e) => {
setName(e.target.value)
localStorage.setItem("name",e.target.value)
}
return (
<div className="name-demo">
{name && <div className="hello">Hello {name}</div>}
<input type="text" name="name" value={name} onChange={handleNameChange}/>
</div>
);
}
export default Name;

Outcome

As you can see in the image below all tabs are synchronized when changing on one tab.

Give it a try for yourself and I hope it was useful for your project.🎉

--

--