简体   繁体   English

如何更新嵌套在 ReactJS 对象中的数组的属性

[英]How to update properties of an array nested inside objects in ReactJS

I have simplified my large data set as follows,我将我的大数据集简化如下,

let state = {
    someProp: {
        someOtherProp: [
            {
                key1: "value1",
                key2: "value2"
            },
            {
                key1: "value3",
                key2: "value4"
            }
        ]
    }
}

I want to update the key1 prop of 0th index of someOtherProp, say to "value5".我想更新 someOtherProp 的第 0 个索引的 key1 属性,比如“value5”。

Tried the following尝试了以下

let newState = {
    ...state, 
        someProp: 
            {...state.someProp, 
                someOtherProp: 
                    {...state.someProp.someOtherProp, 
                        [0]: 
                           {...state.someProp.someOtherProp[0], 
                               key1 : "value5"
                           }
                    }
            }
}

document.write(JSON.stringify(newState));

Output :输出 :

    {
       "someProp": {
          "someOtherProp": {
               "0": {
                      "key1":"value5",
                      "key2":"value2"
                    },
               "1": {
                       "key1":"value3",
                       "key2":"value4"
                    }
           }
        }
      }

But it will convert someOtherProp from array of objects to just nested array.但它会将 someOtherProp 从对象数组转换为嵌套数组。 I know that the problem is with "[0] : ..." statement.我知道问题出在 "[0] : ..." 语句上。 Not sure how to write it.不知道怎么写。 Please help.请帮忙。 New to JS and ReactJS. JS 和 ReactJS 的新手。

The problem you are having is that you're using an object literal instead of an array literal when you define the new someOtherProp.您遇到的问题是,在定义新的 someOtherProp 时,您使用的是对象文字而不是数组文字。

Try this:尝试这个:

let newState = {
    ...state, 
        someProp: 
            {...state.someProp, 
                someOtherProp: 
                    [
                       // create a new first element, using the existing, and overridding key1
                       {...state.someProp.someOtherProp[0], 
                               key1 : "value5"
                       },
                       // append all other someOtherProps except for the first one
                       ...state.someProp.someOtherProp.slice(1)
                    ]
            }
}

You're creating an object, not an array, for someOtherProp :您正在为someOtherProp创建一个对象,而不是一个数组:

someOtherProp: 
    {...state.someProp.someOtherProp, 
        [0]: 
           {...state.someProp.someOtherProp[0], 
               key1 : "value5"
           }
    }

Create an array instead.而是创建一个数组。 I'd do it before the big object literal:我会在大对象文字之前这样做:

const someOtherProp = [...state.someProp.someOtherProp];
someOtherProp[0] = {
    ...state.someProp.someOtherProp[0]
    key1 : "value5"
};

then:然后:

const someOtherProp = [...state.someProp.someOtherProp];
someOtherProp[0] = {
    ...state.someProp.someOtherProp[0]
    key1 : "value5"
};
let newState = {
    ...state, 
        someProp: 
            {...state.someProp,  someOtherProp}
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^
}

But if you want, you can do it inline instead:但如果你愿意,你可以改为内联:

someOtherProp: 
    [
// −^   {...state.someProp.someOtherProp[0],      // Note this is first
            key1 : "value5"
        },
        ...state.someProp.someOtherProp.slice(1)  // Note skipping the first
    ]
// −^

I don't think you need to force it into one statement.我认为您不需要将其强加于一个声明中。

JS's syntax is not that flexible to do this. JS 的语法不是那么灵活。

Forcing it too far may hurt cpu-time.强迫它太远可能会损害 CPU 时间。 (eg when using filter to copy the array to a new one) (例如,当使用过滤器将数组复制到一个新数组时)

const newSomeOtherProp = state.someProp.someOtherProp.slice();
newSomeOtherProp[0] = {...newSomeOtherProp[0], key1: "value5"};

const newState = { 
  ...state,
  someProps: { 
    ...state.someProp,
    someOtherProp: newSomeOtherProp
  }
};

someOtherProp is an array but it is being treated as an object. someOtherProp是一个数组,但它被视为一个对象。 This a generic approach:这是一种通用方法:

const index_to_modify = 0;
const key_to_modify = "key1";
const new_value = "value5";

const newState = {
    ...state,
    someProp: {
        ...state.someProp,
        someOtherProp: state.someProp.someOtherProp.map((item, index) => {
            if (index !== index_to_modify) {
                return item;
            }

            return {
                ...item,
                [key_to_modify]: new_value
            };
        })
    }
};

But as you can see this gets difficult to read and modify.但是正如您所看到的,这很难阅读和修改。 When dealing with nested data you might want to separate concerns for each part of the data.在处理嵌套数据时,您可能希望将数据的每个部分的关注点分开。 Also there are tools that can be handy such as immer .还有一些可以方便的工具,例如immer

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

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