javascript localStorage getItem()方法未检索数据

xzv2uavs  于 2023-01-04  发布在  Java
关注(0)|答案(3)|浏览(185)

我正在尝试从浏览器本地存储获取项目,但无法获取,请帮助我。但我无法从localStorage检索存储的数据。我的Web开发人员工具显示存储的数据存在,但当我打开或重新加载页面时,我无法获取数据。

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>
    </>
  );
};

我查了参考资料。但还是不行。

drkbr07n

drkbr07n1#

所有的useEffects在渲染的时候都会运行一次,所以最初你的联系人状态是[],你把它存储到localStorage中。
因此,要解决这个问题,请尝试在存储到localStorage时添加简单的if检查。
有关详细说明,请参见代码中的注解。

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>
    </>
  );
};
4bbkushb

4bbkushb2#

为什么不起作用?

您的第一个useEffect工作正常

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

但是这个setContacts(retrieveContacts)在第二个useEffect运行之前不会更改状态,因此下面的contacts[]

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

如何让它发挥作用?

您可以检查contacts是否不为空,但在移除项目时会导致bug
您可以在每次更改联系人时更新存储:

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>
    </>
  );
};

或者在状态初始化器中加载存储:

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>
    </>
  );
};

或将两种方法结合使用

1yjd4xko

1yjd4xko3#

如前所述

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

当组件装载时,将调用此效果,并且由于在时间点的状态始终是useState默认值中所述的空数组([]),因此这将把本地存储设置为空数组([])。
当应用程序在<StrictMode>中运行时会发生这种情况,这是一件好事。当在StrictMode中时,react运行useEffects两次,以确保存在不安全的生命周期。
所以render和“shouldComponentUpdate”方法都运行了两次。因此出现了问题。
请确保不要禁用严格模式,而是修复生命周期。

相关问题