繁体   English   中英

如何更改嵌套对象数组的 useState

[英]How to change useState for nested array of objects

我有一个状态:

const obj = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

const [newobj, setObj] = useState("obj")

现在我想为 id:2 中的 id:d1 更新学校。 假设旧值为 school: xyz123 现在我想将其更新为 school: newxyz123。 如何使用扩展运算符或其他方法实现此目的?

我尝试了以下代码:

setObj((prevObjects) => {
            const tempIndex = prevObjects.findIndex(
                (item) => item.id === reqdImgID
            );
const newObject = obj[tempIndex].obj_of_names.map((obj) => { 
if (obj.id == reqdID) { 
return {  ...obj, 
school: newSchool,};}
return obj; }););

但我将其作为输出:{ id:"c1", name: "ghi", school: "newxyz123" }

我建议创建一个接收原始数组的函数、一个匹配器函数和一个替换函数。 这个函数的目的是返回一个值改变的新数组。

function mutateObject(array, matcher, replacer) {
    // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function
    return array.map(function (item) {
        return matcher(item) ? {...replacer(item)} : item;
    });
}

然后,使用该函数替换这些值。

mutateObject(obj, group => group.id == "2", group => {
    const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name, school: "newxyz123" }));
    return { ...group, obj_of_names: newNames }
});

这会做什么:

  1. 使用原始数组,找到 id(在根对象中)为“2”的对象。
  2. 应用替换函数,它将:
    1. 使用obj_of_names查找 id 为“d1”的对象。
    2. 使用扩展运算符应用替换函数以返回具有新学校值的新对象。
    3. 返回一个由扩展运算符克隆的带有替换的obj_of_names对象的新对象,其中包含替换的学校值。

当然,您可以通过使用各种库来克隆对象、对其进行变异并返回新对象来改进此代码及其可读性,但如果您想开始,这是一种解决方法。 另外,如果您想更改学校名称,我建议使用@aweimon 引用的答案,但如果您想根据各种条件更改多个对象,您可以改进上述功能。

 const obj = [{ id: "1", obj_of_names: [{ id: "a1", name: "abc", school: "xyz" }, { id: "b1", name: "def", school: "zyx" }, { id: "c1", name: "ghi", school: "pqr" } ] }, { id: "2", obj_of_names: [{ id: "d1", name: "abc123", school: "xyz123" }] } ] function mutateObject(array, matcher, replacer) { // returns a new array, with all elements untouched, except for those that match the matcher function, which are replaced with new objects created by the replacer function return array.map(function(item) { return matcher(item) ? { ...replacer(item) } : item; }); } const updatedObj = mutateObject(obj, group => group.id == "2", group => { const newNames = mutateObject(group.obj_of_names, name => name.id === "d1", name => ({ ...name, school: "newxyz123" })); return { ...group, obj_of_names: newNames } }); console.log(updatedObj);

const arr = [{id: "1", obj_of_names: [{
                             id: "a1",
                             name: "abc",
                             school: "xyz" },
                            { id:"b1",
                             name: "def",
                             school: "zyx" },
                            { id:"c1",
                             name: "ghi",
                             school: "pqr" }]
             },
             {id: "2", obj_of_names: [{
                             id: "d1",
                             name: "abc123",
                             school: "xyz123" }]
             }]

您可以在另一个地图中调用地图并更改对象中的数组,如下所示:

const newArr =  arr.map((item)=>{
        if(item.id == 2){
            return {...item, obj_of_names: item.obj_of_names.map((item2)=>{
    
                if(item2.id === 'd1'){
                    return {...item2, school: 'newxyz123'}
                }
    
                return item2
            }) }
        }
    
        return item
    })

    const [state, setState] = useState(arr)

然后你可以调用setState并用newArr更新它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM