我有一个相当复杂/嵌套的redux商店,如下所示:
{
object1
{
array:
[
object[1]: {
id: 1,
replace: ""
}
object[2]: {
id: 2
replace: ""
}
object[3]: {
id: 3,
replace: ""
}
]
}
}
在调度动作之后,我需要根据ID将动作插入到对象[]之一。我目前正在使用以下脚本来更新reducer中的 replace 。但是,由于 object2:{} 的大括号,这会将数组更改为对象。
case UPDATE:
return {
...state,
object1: {
...state.object1,
array: {
...state.object1.array,
[action.id]: {
...state.object1.array[action.id],
replace: action.result
}
}
}
};
之后我的渲染会中断,因为在更改为对象后,object2.map不再是一个函数。如何在不将其转换为对象的情况下解决此问题?
以下将因语法错误而失败:
case UPDATE:
return {
...state,
object1: {
...state.object1,
array: [
...state.object1.array,
[action.id]: {
...state.object1.array[action.id],
replace: action.result
}
]
}
};
答案 0 :(得分:1)
您无法使用扩展语法直接指定要修改的索引,您需要先找到索引并按照
进行操作case UPDATE:
var idx = state.object1.object2.findIndex(obj => obj.id === action.id)
return {
...state,
object1: {
...state.object1,
object2: [
...state.object1.object2.slice(0, idx),
{
...state.object1.object2[idx],
replace: action.result
}
...state.object1.object2.slice(idx + 1)
]
}
};
否则你可以使用immutability-helper包。有关如何操作的示例,请参阅此答案
how to use Immutability helper to update a nested object within an array?
答案 1 :(得分:1)
'您可以查看库immutadot。它的目的是帮助以非常简洁的方式更新复杂的嵌套数据结构,并在创建时考虑到redux的使用。
在你的情况下,你可以这样写:
import { set } from 'immutadot'
...
case UPDATE:
return set(state, 'object1.arrary[' + id + '].replace', action.result)
// or with templated string
return set(state, `object1.arrary[${ id }].replace`, action.result)
...
它依赖于木材下的lodash,因此你可以使用lodash功能的所有功能。
答案 2 :(得分:0)
使用immutability-helper包的代码。
case UPDATE:
return update(state, {
object1: {
array: {
[action.id]: {
replace: {
$set: action.result
},
},
},
}
});