React Native中如何匹配placeId修改useState数组对象的productCode?
修复React Native中useState更新数组对象的问题
初始代码与数据
我在React Native中使用useState Hook定义了box状态,初始值通过targetFarm.children处理得到:
const [box, setBox] = useState( targetFarm.children.flatMap((item) => item.children.map((v) => ({ placeId: v.placeId, productCode: v.productCode })) ) )
初始box值:
box = [ { placeId: 257, productCode: "INSECT3"}, { placeId: 258, productCode: "INSECT3"}, { placeId: 259, productCode: "INSECT5"}, { placeId: 260, productCode: "INSECT5"} ]
同时我有hi[0]数据:
hi[0] = { children : [ {placeId: 257, productCode: "INSECT3"}, {placeId: 258, productCode: "INSECT3"}, ] }
需求
当box中对象的placeId与hi[0].children中对象的placeId匹配时,通过setBox修改对应对象的productCode为"INSECT4"。
当前错误代码
hi[0].children.map((v) => { box.map((item) => { if (v.placeId === item.placeId) { // data : "INSECT4" setBox({ productCode: data }) } }) })
异常结果
运行后box的值出现异常:
box = [ { placeId: 257, productCode: "INSECT3" }, ..., productCode: "INSECT4" // 此处结构异常 ]
期望结果
box = [ { placeId: 257, productCode: "INSECT4"}, { placeId: 258, productCode: "INSECT4"}, { placeId: 259, productCode: "INSECT5"}, { placeId: 260, productCode: "INSECT5"} ] // 注:若实际需求是仅保留匹配项,可参考下方方案二
问题原因
- 状态替换错误:直接用
setBox({ productCode: data })把整个box数组替换成了单个对象,彻底破坏了原数组结构。 - 多次触发更新:嵌套
map会多次调用setBox,每次更新都会覆盖之前的状态,且基于旧的box值更新,容易导致状态不一致。
修复方案
方案一:修改匹配项,保留原数组结构
先提取需要更新的placeId集合,遍历数组修改对应项后一次性更新状态:
// 提取目标placeId,用Set提升匹配效率 const targetPlaceIds = new Set(hi[0].children.map(item => item.placeId)); // 创建新数组,修改匹配项的productCode const updatedBox = box.map(item => { if (targetPlaceIds.has(item.placeId)) { // 返回新对象,遵循React状态不可变原则 return { ...item, productCode: "INSECT4" }; } // 不匹配的项直接返回原对象 return item; }); // 一次性更新状态 setBox(updatedBox);
方案二:仅保留匹配项(符合你给出的精简期望结果)
如果需要最终box只包含匹配的项,可结合filter和map:
const targetPlaceIds = new Set(hi[0].children.map(item => item.placeId)); const updatedBox = box .filter(item => targetPlaceIds.has(item.placeId)) .map(item => ({ ...item, productCode: "INSECT4" })); setBox(updatedBox);
内容的提问来源于stack exchange,提问作者user19476497
相关产品推荐
相关产品推荐

