Update nested data arrays of object (Redux)

2020-04-08 14:55发布

I have an issue with updating the immutable redux and quite nested data. Here's an example of my data structure and what I want to change. If anyone could show me the pattern of accessing this update using ES6 and spread operator I would be thankful.

3条回答
男人必须洒脱
2楼-- · 2020-04-08 15:22

This is a longer solution but might help you as your redux state grows. I've also changed some of the values in the original state to make a clearer explanation.

const formCanvasInit = {
  id: 'AAAAXXXX',
  fieldRow: [
    {
      id: 1001,
      fieldGroup: [
        {type: 'text1', inputFocused: true}, // I want to change inputFocused value
        {type: 'text2', inputFocused: false},
      ]
    },
    {
      id: 1002,
      fieldGroup: [
        {type: 'text3', inputFocused: true},
        {type: 'text4', inputFocused: true},
      ]
    }
  ]
};

// the id of the field row to update
const fieldRowID = 1001;
// the value of the field type to update
const fieldTypeValue = 'text1';
const fieldRow = [...formCanvasInit.fieldRow];

// obtain the correct fieldRow object
const targetFieldRowIndex = formCanvasInit.fieldRow.findIndex(fR => fR.id === fieldRowID);
let fieldRowObj = targetFieldRowIndex && formCanvasInit.fieldRow[targetFieldRowIndex];

// obtain that fieldRow object's fieldGroup
const fieldGroup = [...fieldRowObj.fieldGroup];

// obtain the correct object in fieldGroup
const fieldIndex = fieldGroup.findIndex(fG => fG.type === fieldTypeValue);
const fieldToChange = fieldIndex && fieldGroup[fieldIndex];

// replace the old object in selected fieldGroup with the updated one
fieldGroup.splice(fieldIndex, 1, {...fieldToChange, inputFocused: false});

// update the target fieldRow object
fieldRowObj = {...fieldRowObj, fieldGroup};

// replace the old fieldGroup in selected fieldRow with the updated one
fieldRow.splice(targetFieldRowIndex, 1, fieldRowObj);

// create the new formCanvasInit state
const newFormCanvasInit = {...formCanvasInit, fieldRow};
查看更多
Deceive 欺骗
3楼-- · 2020-04-08 15:23

This should do the trick, assuming the data is set up exactly as shown, with the given array indices:

const newData = {
   ...formCanvasInit,
   fieldRow: [{
      ...formCanvasInit.fieldRow[0],
      fieldGroup: [
         { ...formCanvasInit.fieldRow[0].fieldGroup[0], inputFocused: newValue },
         ...formCanvasInit.fieldRow[0].fieldGroup.slice(1, formCanvasInit.fieldRow[0].fieldGroup.length)
      ]
   }]
};

If index of the element to be changed is to be determined dynamically, you'll need to use functionality such as filter to find and remove the array element you're updating, and then spread the corresponding subarrays by editing the structure of the call to slice.

查看更多
甜甜的少女心
4楼-- · 2020-04-08 15:27

Try using Immutability Helper

I think in your structure, like this

let news = update(formCanvasInit, {
  fieldRow: [{
    fieldGroup: [
     { $set: {type: "number", inputFocused: false}}
    ]
  }]
})

I've tried it Click Me

查看更多
登录 后发表回答