使用splice方法从localStorage删除数据时总是删最后一项的解决办法
解决React中删除localStorage数据时总是删最后一项的问题
问题原因
itemArray未同步状态更新:itemArray是组件初始化时从localStorage读取的普通变量,后续新增数据时只有object状态会更新,itemArray始终保持初始值。用它执行splice时,索引和当前渲染的数组对应不上,导致删错项。- 强制刷新页面的不合理性:
window.location.reload()是反React的做法,应该通过更新状态触发重渲染,而非强制刷新页面。 - 列表项缺少唯一标识:map渲染时未给元素加唯一
key,会导致React无法准确识别列表项,可能加剧渲染异常。
修复后的代码
import React, { useEffect, useState } from "react"; import { v4 as uuidv4 } from "uuid"; const Home = () => { const [object, setObject] = useState(() => { // 函数式初始化避免每次渲染重复读取localStorage const storedItems = localStorage.getItem("value"); return storedItems ? JSON.parse(storedItems) : []; }); const [objectValue, setObjectValue] = useState({ price: "", name: "" }); const handleChange = (e) => { const { value, name } = e.target; setObjectValue(prev => ({ ...prev, [name]: value })); }; const handleSubmit = (e) => { e.preventDefault(); // 仅在提交时生成唯一ID,避免输入过程中重复生成 const newItem = { ...objectValue, id: uuidv4() }; setObject(prev => [...prev, newItem]); setObjectValue({ price: "", name: "" }); }; useEffect(() => { // 状态更新时自动同步到localStorage localStorage.setItem("value", JSON.stringify(object)); }, [object]); const handleDelete = (itemId) => { // 基于当前状态过滤生成新数组,更新状态触发重渲染 setObject(prev => prev.filter(item => item.id !== itemId)); }; return ( <div> <form onSubmit={handleSubmit}> <input name="price" onChange={handleChange} value={objectValue.price} placeholder="价格" /> <input name="name" onChange={handleChange} value={objectValue.name} placeholder="名称" /> <button type="submit">提交</button> </form> <div> {object.map((item) => ( <div key={item.id}> {/* 添加唯一key确保React正确跟踪列表项 */} <h1>{item.price}</h1> <button onClick={() => handleDelete(item.id)}>删除</button> </div> ))} </div> </div> ); }; export default Home;
关键修复点
- 基于状态操作数据:删除时不再依赖旧的
itemArray,而是直接使用当前的object状态,通过filter生成新数组并更新状态,让React自动触发重渲染,同时借助useEffect同步到localStorage。 - 用唯一ID替代索引删除:通过item的
id定位要删除的项,彻底避免索引不匹配的问题,这也是React列表操作的标准实践。 - 优化ID生成逻辑:把uuid生成从输入阶段移到提交阶段,避免输入过程中频繁生成无效ID。
- 移除强制刷新:删掉
window.location.reload(),让状态驱动页面渲染,符合React的设计理念。
内容的提问来源于stack exchange,提问作者Mustafa Utku Ergün
相关产品推荐
相关产品推荐

