React中如何向对象数组内对象的desc数组添加对象
问题:向指定工作项的desc数组添加新元素
我已经实现了addWork函数,可以向workArray中添加工作项对象:
const addWork = () => { setWorkArray([...workArray, { id: uniqid(), company: '', title: '', dateFrom: '', dateTo: '', desc: [], editing: true }]); };
但在实现addWorkDesc函数时遇到问题,该函数需要向指定itemId的工作项的desc数组中添加新对象。当前的函数写法存在错误:
const addWorkDesc = (itemId) => { let f; const inOf = workArray.filter((item, index) => { f = index; return item.id == itemId; }); setWorkArray({ ...workArray, ...workArray[f].desc, desc: [{ id: uniqid(), item: '', editing: true }] }); };
预期的workArray结构如下:
[ { id: '1asd5y', // 由uniqid()生成 company: 'some company', title: 'peon', dateFrom: 'fall 2012', dateTo: 'spring 2014', desc: [ { id: '5d554ty', // 由uniqid()生成 item: 'some text here', editing: true }, { id: '9s9d87f', // 由uniqid()生成 item: 'some text here', editing: true }, ], editing: true }, { id: '0s09d8f', // 由uniqid()生成 company: 'some company', title: 'peon', dateFrom: 'fall 2012', dateTo: 'spring 2014', desc: [ { id: '34kjh5', // 由uniqid()生成 item: 'some text here', editing: true }, { id: '77cvb7', // 由uniqid()生成 item: 'some text here', editing: true }, ], editing: true }, ]
正确实现方式
原来的写法存在几个问题:
- 使用
filter获取索引的逻辑不可靠,若有多个匹配项,f会被最后一个索引覆盖;若无匹配项,workArray[f]会报错 - 调用
setWorkArray时错误地将数组转为对象,破坏了原有的数组结构 - 更新
desc时没有保留原有元素,直接替换为新数组,还错误合并了无关属性
正确的实现应该通过遍历数组找到目标项,更新其desc数组,同时保持其他项不变,并且使用React状态的函数式更新来避免异步状态问题:
const addWorkDesc = (itemId) => { setWorkArray(prevWorkArray => prevWorkArray.map(item => { // 找到目标工作项 if (item.id === itemId) { return { ...item, // 保留原工作项的所有属性 desc: [...item.desc, { id: uniqid(), item: '', editing: true }] // 扩展原desc数组,添加新元素 }; } // 非目标项直接返回原对象 return item; }) ); };
逻辑说明:
- 使用
setWorkArray的函数形式,接收prevWorkArray作为参数,确保获取到最新的状态值 - 通过
map遍历数组,对每个工作项进行判断 - 匹配到目标
itemId时,返回一个新对象:展开原工作项的属性,然后将desc更新为原数组加上新的描述对象 - 未匹配到的项直接返回原对象,保证其他状态不受影响
内容的提问来源于stack exchange,提问作者Chris Williamson
相关产品推荐
相关产品推荐

