Home > Enterprise >  localStorage getItem() Method is not retrieving data
localStorage getItem() Method is not retrieving data

Time:01-03

I am trying to get the Items from Browser Local Storage, but unable, please help me out. But I can't retrieve the stored data from localStorage. My Web Developer Tools show me that stored Data exists, but when I turn or reload the page, i won't get the data.

const LOCAL_STORAGE_KEY = "contacts";

const App = () => {
  const [contacts, setContacts] = useState([]);

  const addContactHandler = (contact) => {
    console.log(contact);
    setContacts([...contacts, contact]);
  };


  useEffect(() => {
    const retrieveContacts = JSON.parse(
      localStorage.getItem(LOCAL_STORAGE_KEY)
    );
    if (retrieveContacts) {
      setContacts(retrieveContacts);
    }
  }, []);


  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts));
  }, [contacts]);

  return (
    <>
      <div className="app">

        <Header />
        <AddContact addContactHandler={addContactHandler} />
        <ContactList contacts={contacts} />

      </div>
    </>
  );
};

I checked out the references. But still it is not working.

CodePudding user response:

All useEffects are run for one time at the time of rendering. So initially your contacts state is [] and you are storing it into localStorage.

So to solve it, try adding simple if check while storing into localStorage.

See comment in code for more explanation.

const LOCAL_STORAGE_KEY = "contacts";

const App = () => {
  const [contacts, setContacts] = useState([]);

  const addContactHandler = (contact) => {
    console.log(contact);
    setContacts([...contacts, contact]);
  };


  useEffect(() => {
    const retrieveContacts = JSON.parse(
      localStorage.getItem(LOCAL_STORAGE_KEY)
    );
    if (retrieveContacts) {
      setContacts(retrieveContacts);
    }
  }, []);


  useEffect(() => {
    if(contacts.length) { // Only store if contacts is not empty
       localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts));
    }
  }, [contacts]);

  return (
    <>
      <div className="app">

        <Header />
        <AddContact addContactHandler={addContactHandler} />
        <ContactList contacts={contacts} />

      </div>
    </>
  );
};



CodePudding user response:

Be sure that you are correctly setting the contacts in Local Storage. You can check this by opening the Web Developer Tools and inspecting the Local Storage and also that you are correctly parsing the stored contacts from Local Storage. You can check this by adding a console.log(retrieveContacts)statement after the line const retrieveContacts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)). This will log the retrieved contacts to the console, which will allow you to see if there are any errors while parsing the stored contacts.

Also, you want to make sure that you are correctly handling the case where no contacts are found in Local Storage. In this case, localStorage.getItem(LOCAL_STORAGE_KEY) will return null, and calling JSON.parse(null) will result in a SyntaxError. You can handle this by adding a check for null before calling JSON.parse(), like this:

const retrieveContacts = localStorage.getItem(LOCAL_STORAGE_KEY);
if (retrieveContacts) {
  setContacts(JSON.parse(retrieveContacts));
}

CodePudding user response:

Why doesn't it work?

Your first useEffect is working fine

useEffect(() => {
  const retrieveContacts = JSON.parse(
    localStorage.getItem(LOCAL_STORAGE_KEY)
  );
  if (retrieveContacts) {
    setContacts(retrieveContacts);
  }
}, []);

But this setContacts(retrieveContacts) doesn't change the state before the second useEffect runs so contacts below is []

useEffect(() => {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts));
}, [contacts]);

How to make it work?

You could check if contacts is not empty, but it will cause bugs when removing items

You can either update the store every time you change contacts:

const LOCAL_STORAGE_KEY = "contacts";

const App = () => {
  const [contacts, setContacts] = useState([]);

  const addContactHandler = (contact) => {
    const newContacts = [...contacts, contact];
    setContacts(newContacts);
    updateStorage(newContacts);
  };

  useEffect(() => {
    const retrieveContacts = JSON.parse(
      localStorage.getItem(LOCAL_STORAGE_KEY)
    );
    if (retrieveContacts) {
      setContacts(retrieveContacts);
    }
  }, []);

  const updateStorage = (items) => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(items));
  };

  return (
    <>
      <div className="app">
        <Header />
        <AddContact addContactHandler={addContactHandler} />
        <ContactList contacts={contacts} />
      </div>
    </>
  );
};

Or load the store in the state initializer:

const LOCAL_STORAGE_KEY = "contacts";

const App = () => {
  const [contacts, setContacts] = useState(() => {
    const retrieveContacts = JSON.parse(
      localStorage.getItem(LOCAL_STORAGE_KEY)
    );
    if (retrieveContacts) {
      return retrieveContacts;
    }

    return [];
  });

  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts));
  }, [contacts]);

  const addContactHandler = (contact) => {
    const newContacts = [...contacts, contact];
    setContacts(newContacts);
    updateStorage(newContacts);
  };

  return (
    <>
      <div className="app">
        <Header />
        <AddContact addContactHandler={addContactHandler} />
        <ContactList contacts={contacts} />
      </div>
    </>
  );
};

Or combine both approaches

  • Related