'How do i re-run useEffect hook if the localstorage value has been changed?

I'm trying to re-run the useEffect hook based if any new item has been added to the localstorage.

My useEffect looks like this :

useEffect(() => {
      //getting all localstorage items and setting to a variable
      const localStorageItems = { ...localStorage }

      // filtering out the localstorage items for keys that only starts with "HTTP" & pushing it to the state called "testData" using setTestData useState hook.
    
      const filteredByKey = Object.fromEntries(
        Object.entries(localStorageItems).filter(([key, value]) => {
          if (key.startsWith("http")) {
            testArr2.push({ urls: [key, value] })
            // setTestData({ urls: [key, value] })
            setTestData((prev) => [...prev, { key, value }])
          }
        })
      )
    }, [])

My problem is when I hit a button(adding a new data) this useEffect should ideally re-run, setting the latest data to the "testData" state.

The Problem :

  • I cannot pass window.localstorage to the useEffect's array dependency list, as it is external variable I believe and react doesn't allow it.

What I have tried:

  • I have looked at this answer on SO, but my situation is a bit complex as I'm loading the entire items to a variable first(I'm not aware of any better alternatives)
  • I have tried to put the state value in the dependency list, but it doesn't work and goes to infinite loop.

Please help. Thanks for reading this far.



Solution 1:[1]

i can give you a work around for this use case, create react context that syncs with localStorage. you can use the context as a useEffect dependency. sync means, take the value from localStorage at starting and update the context along with the localStorage from your app.

Solution 2:[2]

Define a state that holds the local storage value and pass it as a useEffect parameter.

const [localStorageData, setLocalStorageData] = useState([]);

useEffect(() => {

    // Your codes

}, [localStorageData])

Solution 3:[3]

you can use 'storage' event listener

window.addEventListener('storage', function(e) {
  if (e.newValue) {
    console.log('new data is saved ...')
    // ...... your code
  }
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dev-2019
Solution 2 Serkan Çamkerten
Solution 3 Mohamed Sayed