簡體   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