新闻中心
解决React应用中从LocalStorage渲染数据的问题

本文旨在解决React应用中从LocalStorage加载数据时,数据无法在页面刷新或重新加载后正确渲染的问题。通过分析常见原因,并提供详细的代码示例,帮助开发者理解如何正确地在React组件中使用`useEffect`钩子和LocalStorage,以确保数据的持久化和正确渲染。
在React应用中,从LocalStorage读取数据并在组件中渲染是一个常见的需求。然而,开发者经常遇到页面刷新或重新加载后,LocalStorage中的数据无法正确渲染的问题。这通常是由于对useEffect钩子的不当使用以及LocalStorage的写入时机造成的。
问题分析
问题的核心在于,在组件初始化时,contacts状态变量被初始化为空数组 []。随后,useEffect钩子尝试将此空数组写入LocalStorage。这导致每次页面加载时,LocalStorage中的数据都被重置为空,从而导致渲染问题。
const [contacts, setContacts] = useState([
{
id: Math.random().toString(36).substr(2, 9),
fullName: "Vekjko Petrovic",
address: "121 Town Commons Way Phoenix, AZ, 45215",
phone: 123_465_689,
date,
},
{
id: Math.random().toString(36).substr(2, 9),
fullName: "Marko Petrovic",
address: "Srbina 35, 11300 Smederevo Srbija",
phone: 256_269_866,
date,
},
{
id: Math.random().toString(36).substr(2, 9),
fullName: "Michael Jackson",
address: "52 City St, Detroit, Mi, 46218",
phone: 359_525_555,
date,
},
{
id: Math.random().toString(36).substr(2, 9),
fullName: "Vanessa Parady",
address: "11 Beogradska Beograd, SRB, 11000",
phone: 123_465_689,
date,
},
]);
useEffect(() => {
const s*edContacts = JSON.parse(localStorage.getItem("contacts"));
if (s*edContacts) {
setContacts(s*edContacts);
}
}, []);
useEffect(() => {
localStorage.setItem("contacts", JSON.stringify(contacts));
}, [contacts]);上述代码中,第一个useEffect尝试从LocalStorage加载数据,第二个useEffect则在每次contacts状态更新时将数据写入LocalStorage。问题在于,组件首次渲染时,contacts的初始值(即使有初始值)会立即触发第二个useEffect,覆盖LocalStorage中的数据。
解决方案
为了解决这个问题,需要调整LocalStorage的写入时机,避免在组件初始化时覆盖已有的数据。一个推荐的做法是将LocalStorage的写入操作放在添加或修改联系人的函数中。
以下是修改后的代码示例:
PHP经典实例(第二版)
PHP经典实例(第2版)能够为您节省宝贵的Web开发时间。有了这些针对真实问题的解决方案放在手边,大多数编程难题都会迎刃而解。《PHP经典实例(第2版)》将PHP的特性与经典实例丛书的独特形式组合到一起,足以帮您成功地构建跨浏览器的Web应用程序。在这个修订版中,您可以更加方便地找到各种编程问题的解决方案,《PHP经典实例(第2版)》中内容涵盖了:表单处理;Session管理;数据库交互;使用We
470
查看详情
import React, { useState, useEffect } from "react";
export const Contacts = () => {
const [contacts, setContacts] = useState([]);
useEffect(() => {
const s*edContacts = localStorage.getItem("contacts");
if (s*edContacts) {
setContacts(JSON.parse(s*edContacts));
}
}, []);
const addContact = (newContact) => {
const newContactList = [...contacts, newContact];
setContacts(newContactList);
localStorage.setItem("contacts", JSON.stringify(newContactList));
};
retu
rn (
<div>
<InputContact addContact={addContact} />
{contacts.map((data, i) => (
<Contact data={data} key={i} />
))}
</div>
);
};
const InputContact = ({addContact}) => {
const [fullName, setFullName] = useState('');
const handleS*eClick = () => {
if (fullName.trim().length > 0) {
addContact({ fullName, id: Math.random().toString(36).substr(2, 9) });
setFullName('');
}
};
return (
<div>
<input
type="text"
placeholder="Enter Full Name"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
/>
<button onClick={handleS*eClick}>Add Contact</button>
</div>
);
};
const Contact = ({data}) => {
return (
<div>
{data.fullName}
</div>
);
};在这个修改后的示例中,LocalStorage的写入操作被移动到了addContact函数中。只有在添加新联系人时,才会更新LocalStorage中的数据。
关键改进:
- 移除不必要的useEffect: 删除了在每次contacts状态更新时写入LocalStorage的useEffect。
- 在addContact函数中写入LocalStorage: 在添加新联系人后,立即更新LocalStorage,确保数据持久化。
总结
正确使用useEffect钩子和LocalStorage对于构建持久化的React应用至关重要。避免在组件初始化时覆盖LocalStorage中的数据,并将LocalStorage的写入操作放在适当的事件处理函数中,可以有效地解决数据渲染问题。
注意事项:
- 确保在写入LocalStorage之前,将数据转换为JSON字符串 (JSON.stringify())。
- 在从LocalStorage读取数据后,将其解析为J*aScript对象 (JSON.parse())。
- 避免频繁地写入LocalStorage,因为这可能会影响性能。
- 考虑使用更高级的状态管理方案(如Redux、Context API或MobX)来管理复杂应用的状态,尤其是在需要跨组件共享状态时。
通过遵循这些最佳实践,可以确保React应用能够正确地从LocalStorage加载和渲染数据,提供更好的用户体验。
以上就是解决React应用中从LocalStorage渲染数据的问题的详细内容,更多请关注其它相关文章!
# 正确地
# 日照网站建设商家有哪些
# 许昌企业网站建设推广
# 长安网站建设优化公司
# 网站优化简历修改服务号
# 鄂州市网站做优化代理
# 相城网站优化推广方案
# 石龙抖音seo策划
# 免费优化网站运营简历
# 云南建设网站有哪些
# 秦皇岛seo公司排名
# 为空
# 如何实现
# react
# 翻页
# 第二个
# 多个
# 在这个
# 表单
# 放在
# 加载
# red
# json
# js
# java
# javascript
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
React列表渲染与独立状态管理:避免全局状态影响局部更新
Descript怎样用AI剪辑自动去噪_Descript用AI剪辑自动去噪【自动降噪】
J*aScript数组对象转换:按指定键分组与值收集
mcjs网页版流畅运行 mcjs低配电脑畅玩入口
Win10如何清理注册表垃圾 Win10手动清理无效注册表【技巧】
excel如何生成目录 excel一键生成工作表目录超链接
J*a中实现Go语言select通道多路复用机制
J*a应用集成GitHub CLI与API认证指南
天猫2025双十一0点秒杀攻略 天猫爆款抢购时间
精准捕获:如何在页面中监听除特定元素外的所有点击事件
探索高级语言到C/C++的转译路径:以Go为例及内存管理策略
windows10怎么关闭系统提示音_windows10彻底静音设置方法
vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法
ArrayList与LinkedList操作复杂度详解:遍历与修改
单射、满射与双射的关系 一文理清所有逻辑
支付宝如何管理隐私设置_支付宝隐私保护的配置技巧
深入理解J*aScript Promise异步执行与微任务队列
Lar*el头像管理:图片缩放与旧文件删除的最佳实践
DLsite中文平台入口 DLsite官网内容在线查看
VS Code远程开发时如何处理文件权限问题
微博网页版首页入口 微博电脑端官网登录链接
CSS布局中意外空白:解决padding-top导致的顶部间距问题
163邮箱官方主页登录 直达网易邮箱登录核心页面
sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置
不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|
qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决
如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构
b站如何看历史记录_b站观看历史找回方法
J*aScript数据结构转换:将对象数组按类别分组
如何在Promise链中优雅地中断后续then执行
Pandas DataFrame:高效添加条件计算列
如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension
J*a里如何使用forEach遍历Map_Map遍历方法说明
JUnit5/Mockito:优雅测试内部依赖与异常处理的实践
c++中的std::basic_string的SSO优化_c++短字符串优化深度解析
必由学官方登录入口 必由学教师学生账号快速访问
纯CSS与HTML网格布局的HTML精简策略:SVG与JS方案解析
Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】
12306选座如何查看座位示意图_12306座位示意图解读与使用
打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门
如何将一个大型PHP应用拆分为多个Composer包_微服务与模块化架构的Composer实践
微信群消息显示延迟如何解决 微信群消息刷新优化方法
C++ explicit关键字防止隐式转换_C++构造函数安全规范
处理动态列数据:J*a ArrayList的正确初始化与字符累加教程
Go调试环境为何无法启动_Go调试器启动失败原因与解决策略
手机CPU怎么影响游戏体验_手机CPU对游戏性能的影响分析
mcjs网页版在线存档 mcjs云存档登录入口
1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】
在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南
Golang如何使用const iota_Go iota常量计数器讲解


2025-10-26
浏览次数:次
返回列表
rn (
<div>
<InputContact addContact={addContact} />
{contacts.map((data, i) => (
<Contact data={data} key={i} />
))}
</div>
);
};
const InputContact = ({addContact}) => {
const [fullName, setFullName] = useState('');
const handleS*eClick = () => {
if (fullName.trim().length > 0) {
addContact({ fullName, id: Math.random().toString(36).substr(2, 9) });
setFullName('');
}
};
return (
<div>
<input
type="text"
placeholder="Enter Full Name"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
/>
<button onClick={handleS*eClick}>Add Contact</button>
</div>
);
};
const Contact = ({data}) => {
return (
<div>
{data.fullName}
</div>
);
};