ReactJS中动态键名对象的数组增改实现方案问询
这问题我熟!你现在的核心问题是每次触发select的onChange都会往状态数组里新增对象,导致同name的选项重复积累。之前用findIndex的时候写法错了,动态属性访问不能用.加方括号,得直接用方括号语法。我给你两个优雅的解决方案,看你喜欢哪种:
方案一:用findIndex精准定位替换
这种方法适合需要严格保持数组操作逻辑的场景,先找到对应name的项的索引,再决定是新增还是替换:
function validateVariations(event) { // 解构出当前select的name和value,让代码更清爽 const { name, value } = event.target; setSelected(prevSelected => { // 找到数组中包含当前name键的项的索引 // 用hasOwnProperty判断更严谨,避免原型链上的属性干扰 const targetIndex = prevSelected.findIndex(item => Object.prototype.hasOwnProperty.call(item, name) ); if (targetIndex === -1) { // 没找到对应项,直接新增 return [...prevSelected, { [name]: value }]; } else { // 找到对应项,复制原数组后替换目标位置的内容 const newSelected = [...prevSelected]; newSelected[targetIndex] = { [name]: value }; return newSelected; } }); // ...其他业务逻辑 }
方案二:利用对象键的唯一性简化逻辑
如果你的状态数组里每个对象都只有一个键(就像你例子里的{Weight: "250"}这种),那可以先把数组转成对象,利用对象键的唯一性自动覆盖旧值,最后再转回数组格式,代码会简洁很多:
function validateVariations(event) { const { name, value } = event.target; setSelected(prevSelected => { // 把数组转成一个大对象:{ Weight: "250", Pack: "Tin" } const selectedMap = prevSelected.reduce((acc, item) => { const [key] = Object.keys(item); acc[key] = item[key]; return acc; }, {}); // 直接覆盖或新增当前name对应的value selectedMap[name] = value; // 再把对象转回你需要的数组格式:[{Weight: "250"}, {Pack: "Tin"}] return Object.entries(selectedMap).map(([key, val]) => ({ [key]: val })); }); // ...其他业务逻辑 }
这种写法不用处理索引判断,逻辑更直观,尤其适合你这种每个项都是单键对象的场景。
内容的提问来源于stack exchange,提问作者popeating
相关产品推荐
相关产品推荐

