我已经建立了我的状态
const list = {
categories: {
Professional: {
active: false,
names: [
{
id: 1,
name: "Golf",
active: false
},
{
id: 2,
name: "Ultimate Frisbee",
active: false
}
]
}}
在我的操作中,我添加了ID选项,因此当用户点击选项时,我想更改活动状态
我使用的是Immutable JS虽然没有和它结婚。我想知道如何定位对象的id并在reducer中更新其活动状态?我也愿意就如何更好地改善我的状态提出反馈
答案 0 :(得分:37)
这是非常普遍的事情,而且实际上非常令人生畏。据我所知,普通JS中没有真正优秀且采用良好的解决方案。最初,使用了Object.assign
方法:
return Object.assign({}, state, {
categories: Object.assign({}, state.categories, {
Professional: Object.assign({}, state.Professional, {
active: true
})
})
});
我承认这太简单和麻烦了,但我不得不说我们用这种方法构建了很少的大型应用程序,除了字符数量之外它还不错。如今,最流行的方法是使用Object spread:
return {
...state,
categories: {
...state.categories,
Professional: {
...state.categories.Professional,
active: true
}
}
}
第二种方法更清洁,所以如果你使用普通JS,那么它似乎是一个不错的选择。 在Immutable.js中,我不得不承认它更容易,你只需要做下一个
return state.updateIn(['categories', 'Professional'], x => x.set('active', true));
但它有自己的缺点和警告,所以最好在承诺之前认真考虑它。
关于改善状态的最后一个问题 - 通常最好不要进行如此深度的嵌套(将您的关注点分开,通常字段不依赖于彼此 - 例如active
状态可以分离到另一个对象),但由于不了解您的域名,很难说。此外,normalize您的数据被认为是正常的事情。
答案 1 :(得分:4)
Structuring Reducers上的Redux文档部分介绍了这一点。特别是,请参阅Immutable Update Patterns部分。给出的示例适用于普通的JS对象和数组,但同样的方法适用于列表上的map()
,为不想要更新的所有内容返回现有项目,并返回 想要更新的新版本。
根据文档,还要注意,如果您的数据存储在规范化结构中,则更新特定项目会更容易,因为您可以直接通过ID查找。 “结构化减速器”部分也涵盖了标准化。