我在更新不可变redux和非常嵌套的数据时遇到问题。这是我的数据结构和我想要改变的一个例子。如果有人能告诉我使用ES6和传播运算符访问此更新的模式,我将非常感激。
const formCanvasInit = {
id: guid(),
fieldRow: [{
id: guid(),
fieldGroup: [
{ type: 'text', inputFocused: true }, // I want to change inputFocused value
{ type: 'text', inputFocused: false },
],
}],
// ...
};
答案 0 :(得分:3)
这应该可以解决这个问题,假设数据的设置完全如图所示,具有给定的数组索引:
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)
]
}]
};
如果要动态确定要更改的元素的索引,则需要使用filter
等功能来查找和删除您要更新的数组元素,然后再传播通过编辑对slice
的调用结构来确定相应的子阵列。
答案 1 :(得分:2)
我认为在你的结构中,像这样
let news = update(formCanvasInit, {
fieldRow: [{
fieldGroup: [
{ $set: {type: "number", inputFocused: false}}
]
}]
})
我试过了 Click Me
答案 2 :(得分:1)
这是一个较长的解决方案,但随着您的redux状态的增长可能对您有所帮助。我还改变了原始状态中的一些值,以便做出更清晰的解释。
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};