使用prevState条件更新对象数组状态失效问题求助
问题出在引用类型的比较逻辑上!
你遇到的问题根源在于:对象是引用类型,Array.includes()使用严格相等(===)来判断元素是否存在,而两个内容完全相同的对象,只要不是同一个内存引用,===就会返回false,所以你的prevState.includes(data)永远会判断为“不存在”,导致每次都执行添加操作。
举个直观的例子:
const objA = { id: 1 }; const objB = { id: 1 }; console.log(objA === objB); // 输出 false!因为它们是两个不同的内存引用
解决方法
根据你的对象结构,推荐两种实用方案:
1. 利用对象的唯一标识(最推荐)
如果你的对象有唯一属性(比如id、key这类不会重复的值),用Array.some()来检查数组中是否存在相同标识的对象:
setTogglerStateArray((prevState) => { console.log('data:', data) console.log('prevState:', prevState) // 检查数组中是否存在和data同id的对象 const isAlreadyExist = prevState.some(item => item.id === data.id) if (isAlreadyExist) { return prevState } else { return [...prevState, data] } })
2. 全属性比较(无唯一标识时用)
如果对象没有唯一标识,只能通过比较所有属性来判断是否相同。注意这种方法只适合单层对象(没有嵌套对象),如果是嵌套对象,需要实现深度比较:
// 浅比较两个单层对象的辅助函数 const isObjectEqual = (obj1, obj2) => { // 先比较属性数量是否一致 if (Object.keys(obj1).length !== Object.keys(obj2).length) return false; // 逐个比较属性值 return Object.keys(obj1).every(key => obj1[key] === obj2[key]); } setTogglerStateArray((prevState) => { console.log('data:', data) console.log('prevState:', prevState) const isAlreadyExist = prevState.some(item => isObjectEqual(item, data)) if (isAlreadyExist) { return prevState } else { return [...prevState, data] } })
提示:如果是嵌套对象,自己写深度比较容易出错,也可以用成熟的工具函数(比如lodash的
isEqual),但性能会比用唯一标识差一些,所以优先推荐给对象加唯一标识的方案。
内容的提问来源于stack exchange,提问作者user17817249
相关产品推荐
相关产品推荐

