Search code examples
reactjslocal-storage

Data isn't being retrieved from local storage (React)


I'm just trying to set some contact data in local storage and render on DOM but after reloading the page there is no contact data in localStorage to render in DOM! I tried in other browsers but the result is equal.

here is my code:

import { useEffect, useState } from "react";
import { toast } from "react-toastify";
import ContactForm from "./ContactForm";
import ContactList from "./ContactList";

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

  const addContactHandler = (formValues) => {
    if (!formValues.name || !formValues.email) {
      toast.error("Name and email are required");
      return;
    }
    setContacts([...contacts, { ...formValues, id: Date.now() }]);
  };

  const deleteContactHandler = (id) => {
    setContacts(contacts.filter((contact) => contact.id !== id));
  };

  useEffect(() => {
    const savedContacts = JSON.parse(localStorage.getItem("contacts"));
    if (savedContacts) setContacts(savedContacts);
  }, []);

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

  return (
    <div className="contact-app">
      <nav>
        <h1>Contact Manager</h1>
      </nav>
      <ContactForm onClick={addContactHandler} />
      <ContactList onDelete={deleteContactHandler} contacts={contacts} />
    </div>
  );
};

export default ContactApp;

Solution

  • Here is the explanation:

    When you are calling the function to get the data from localstorage, you are also setting the contacts variable to the new data.

    useEffect(() => {
        const savedContacts = JSON.parse(localStorage.getItem("contacts"));
        if (savedContacts) setContacts(savedContacts); // Here you are changing the value of 'contacts'
    }, []);
    

    BUT, You are also calling the localStorage.setItem method whenever the value of the contacts variable changes.

    useEffect(() => {
        localStorage.setItem("contacts", JSON.stringify(contacts));
    }, [contacts]); // Here you are calling it when the contacts change.
    

    So basically, when the component loads in the first useEffect. You are checking to see if contacts exist and setting the contacts variable to the existing contacts.

    But you are also setting the value of the localStorage WHENEVER the value of the contacts variable changes.

    its like:
    Fetching Data the first time it loads and storing it --> because you have stored the data and the value of contacts has changed, it again sets the value of the contacts ----> which can lead to storing undefined or [] values if the contacts don't already have some default value.

    Hope this helps.