Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

302
Views
React, update and detect localStorage changes with a custom hook across different components

I have a custom hook to manage localStorage like below:

import { useEffect, useState } from 'react'

export default function useLocalStorage(key, initValue) {

    const [state, setState] = useState(() => {
        const value = localStorage.getItem(key);
        if (value !== null) {
            return JSON.parse(value);
        }

        localStorage.setItem(key, JSON.stringify(initValue));
        return initValue;
    })

    useEffect(() => {
        localStorage.setItem(key, state);
    }, [key, state])
    
    return [state, setState];
}

This custom hook is declared to use the same localstorage key for two or more components in one screen. e,g.

const [state, setState] = useLocalStorage('key', false);

At this time, since components using useLocalStorage want to work according to the state change of localStorage, we try to use the state returned by useLocalStorage as the second parameter of useEffect.

useEffect(() => {
   foobar()
}, [state]);

I expected the foobar() function in useEffect to work when the "state" changes in all components that declared this useEffect. However, foobar() only worked for one component out of several components using this same useEffect.Why this is happening? How do I get it to work the way I want it to?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You should set up an event listener for storage changes in order to have the updated value. See the code below and the note about storage event:

import { useEffect, useState } from 'react'

export default function useLocalStorage(key, initValue) {
  const [state, setState] = useState(() => {
    const value = localStorage.getItem(key);
    if (value !== null) {
      return JSON.parse(value);
    }

    localStorage.setItem(key, JSON.stringify(initValue));
    window.dispatchEvent(new Event("storage"));
    return initValue;
  });

  useEffect(() => {
    localStorage.setItem(key, state);
    window.dispatchEvent(new Event("storage"));
  }, [key, state]);

  useEffect(() => {
    const listenStorageChange = () => {
      setState(() => {
        const value = localStorage.getItem(key);
        if (value !== null) {
          return JSON.parse(value);
        }

        localStorage.setItem(key, JSON.stringify(initValue));
        window.dispatchEvent(new Event("storage"));
        return initValue;
      });
    };
    window.addEventListener("storage", listenStorageChange);
    return () => window.removeEventListener("storage", listenStorageChange);
  }, []);

  return [state, setState];
}

You might wonder why this dispatchEvent is used. Well here is what MDN says about storage event:

The storage event of the Window interface fires when a storage area (localStorage) has been modified in the context of another document.

This dispatchEvent is needed as we need to listen to changes in the same document as well.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!