如何确保useState数组与Local Storage中的元素唯一?
解决React中Local Storage观影列表重复添加问题
当前问题:使用useState和Local Storage存储观影列表时,重复点击添加按钮会把同一影片多次存入Local Storage,需要实现添加前检查影片是否已存在,保证列表元素唯一。
现有代码:
const [watchList, setWatchlist] = React.useState([]) React.useEffect(() => { setWatchlist(ls('myList')) },[]) function setWatchListAction(mylist) { setWatchlist(mylist) } const addToMyList = (media) => { // Heres where i add my data let myList; if(ls("myList") !== null){ myList = ls("myList") myList.push(media) ls.set("myList", myList) setWatchlist(myList) } else { ls.set("myList", [media]) window.location.reload(false) } } const RemoveFromList = (mediaId) => { let newlist = [] let myList = ls("myList") myList.filter((items) => { if(items.id !== mediaId.id){ newlist.push(items) } }) ls("myList", newlist) setWatchlist(newlist) }
修改方案:
- 添加重复检查逻辑:在
addToMyList中通过影片id判断是否已存在,不存在再执行添加操作 - 优化删除逻辑:直接利用
filter返回值生成新列表,无需手动push - 移除不必要的页面刷新:状态更新后React会自动重新渲染,不需要调用
window.location.reload
修改后的完整代码:
const [watchList, setWatchlist] = React.useState([]) React.useEffect(() => { // 初始化时处理空值,避免后续操作报错 setWatchlist(ls('myList') || []) },[]) function setWatchListAction(mylist) { setWatchlist(mylist) } const addToMyList = (media) => { let myList = ls("myList") || []; // 通过id检查影片是否已在列表中 const isDuplicate = myList.some(item => item.id === media.id); if (!isDuplicate) { // 用扩展运算符生成新数组,保持不可变更新 const updatedList = [...myList, media]; ls.set("myList", updatedList); setWatchlist(updatedList); } // 已存在则不执行任何操作 } const RemoveFromList = (mediaId) => { let myList = ls("myList") || []; // 直接用filter过滤出需要保留的元素 const newlist = myList.filter(item => item.id !== mediaId.id); ls.set("myList", newlist); setWatchlist(newlist); }
关键说明:
- 重复判断:使用
Array.some()快速检测列表中是否已有相同id的影片,效率高于遍历全量元素 - 不可变更新:添加影片时用扩展运算符生成新数组,符合React状态更新的最佳实践,避免意外的引用问题
- 空值处理:初始化和读取Local Storage时用
|| []兜底,避免null值导致后续数组操作报错 - 删除逻辑简化:
filter方法本身会返回过滤后的新数组,无需手动创建空数组再push元素
内容的提问来源于stack exchange,提问作者kev
相关产品推荐
相关产品推荐

