React应用LocalStorage联系人数据刷新后丢失问题求助
React localStorage刷新后数据丢失问题解决
问题描述
在React应用中尝试将联系人保存到localStorage,添加联系人时数据可成功存入,但刷新页面后localStorage就会被清空,相关代码如下:
import "./App.css"; import "bootstrap/dist/css/bootstrap.css"; import Header from "./Header"; import AddContact from "./AddContact"; // import ContactCard from './ContactCard' import ContactList from "./ContactList"; import { useEffect, useState } from "react"; function App() { const LOCAL_STORAGE_KEY = "contacts"; const [contacts, setContacts] = useState([]); const addContactHandler = (contact) => { setContacts([...contacts, contact]); }; useEffect(() => { console.log("Saving contacts:", contacts); localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts)); }, [contacts]); useEffect(() => { const retriveContacts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)); console.log("Retrieved contacts:", retriveContacts); if (retriveContacts) setContacts(retriveContacts); }, []); return ( <div className="container"> <Header /> <AddContact AddContactHandler={addContactHandler} /> <ContactList contacts={contacts} /> </div> ); } export default App;
问题原因
组件挂载时,useState初始值为空数组,同时两个useEffect的执行顺序会导致数据被覆盖:
- 依赖
contacts的useEffect会在组件挂载时触发,此时contacts是空数组,会直接把空数组存入localStorage,覆盖之前存储的数据。 - 空依赖的
useEffect虽然会读取localStorage数据,但如果前者先执行,就会导致读取到的是空数组,最终页面显示为空。
解决方案
修改初始化逻辑,直接从localStorage读取数据作为useState的初始值,同时移除冗余的读取useEffect:
import "./App.css"; import "bootstrap/dist/css/bootstrap.css"; import Header from "./Header"; import AddContact from "./AddContact"; import ContactList from "./ContactList"; import { useEffect, useState } from "react"; function App() { const LOCAL_STORAGE_KEY = "contacts"; // 初始化时直接从localStorage加载已有数据 const [contacts, setContacts] = useState(() => { const savedContacts = localStorage.getItem(LOCAL_STORAGE_KEY); return savedContacts ? JSON.parse(savedContacts) : []; }); const addContactHandler = (contact) => { setContacts([...contacts, contact]); }; // contacts变化时同步保存到localStorage useEffect(() => { console.log("Saving contacts:", contacts); localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(contacts)); }, [contacts]); return ( <div className="container"> <Header /> <AddContact AddContactHandler={addContactHandler} /> <ContactList contacts={contacts} /> </div> ); } export default App;
修改说明
- 初始化优化:使用函数作为
useState的初始值,组件挂载时直接读取localStorage中的数据,避免初始空数组导致的覆盖问题。 - 移除冗余逻辑:删除了空依赖的
useEffect,因为初始化阶段已经完成了数据读取,无需重复执行。
内容的提问来源于stack exchange,提问作者Abu RayhaN
相关产品推荐
相关产品推荐

