javascript – 状态为对象数组与id键入的对象
作者:互联网
在Designing the State Shape章节中,文档建议将您的状态保存在由ID键入的对象中:
Keep every entity in an object stored with an ID as a key, and use IDs to reference it from other entities, or lists.
他们继续陈述
Think of the app’s state as a database.
我正在处理状态形状以获取过滤器列表,其中一些将打开(它们显示在弹出窗口中),或者已选择选项.当我读到“将应用程序的状态视为数据库”时,我考虑将它们视为JSON响应,因为它将从API(本身由数据库支持)返回.
所以我一直在考虑它
[{
id: '1',
name: 'View',
open: false,
options: ['10', '11', '12', '13'],
selectedOption: ['10'],
parent: null,
},
{
id: '10',
name: 'Time & Fees',
open: false,
options: ['20', '21', '22', '23', '24'],
selectedOption: null,
parent: '1',
}]
但是,文档建议更像一种格式
{
1: {
name: 'View',
open: false,
options: ['10', '11', '12', '13'],
selectedOption: ['10'],
parent: null,
},
10: {
name: 'Time & Fees',
open: false,
options: ['20', '21', '22', '23', '24'],
selectedOption: null,
parent: '1',
}
}
从理论上讲,只要data is serializable (under the heading “State”)就没关系.
所以我愉快地采用了对象阵列方法,直到我写了我的减速器.
使用object-keyed-by-id方法(以及扩展语法的自由使用),reducer的OPEN_FILTER部分变为
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
使用对象数组方法,它更冗长(和辅助函数依赖)
switch (action.type) {
case OPEN_FILTER: {
// relies on getFilterById helper function
const filter = getFilterById(state, action.id);
const index = state.indexOf(filter);
return state
.slice(0, index)
.concat([{ ...filter, open: true }])
.concat(state.slice(index + 1));
}
...
所以我的问题有三个:
1)减速器的简单性是否采用对象键控id方法的动机?这种状态还有其他优点吗?
和
2)看起来像object-keyed-by-id方法使得处理API的标准JSON输入/输出变得更加困难. (这就是我首先使用对象数组的原因.)因此,如果你采用这种方法,你是否只使用一个函数在JSON格式和状态形状格式之间来回转换它?这看起来很笨拙. (虽然如果你提倡这种方法,你的推理是否比上面的对象数组减少器更少笨重?)
和
3)我知道Dan Abramov将redux设计为理论上与状态数据结构无关(正如“By convention, the top-level state is an object or some other key-value collection like a Map, but technically it can be any type,”强调我所建议的那样).但鉴于上述情况,是否只是“建议”将其保持为ID键入的对象,或者是否存在其他无法预料的痛点,我将通过使用一系列对象来解决这个问题,这样我就应该中止计划并尝试坚持使用ID键入的对象?
解决方法:
Q1:reducer的简单性是不必搜索数组以找到正确的条目.不必搜索阵列是有利的.选择器和其他数据访问器可能并且经常通过id访问这些项目.必须在阵列中搜索每次访问都会成为性能问题.当阵列变大时,性能问题会急剧恶化.此外,随着您的应用变得更加复杂,在更多地方显示和过滤数据,问题也会恶化.这种组合可能是有害的.通过id访问项目,访问时间从O(n)变为O(1),对于大n(这里是数组项),访问时间产生巨大差异.
Q2:您可以使用normalizr
来帮助您进行从API到商店的转换.从normalizr V3.1.0开始,你可以使用denormalize来反过来.也就是说,应用程序通常比数据生产者更多的消费者,因此转换到商店通常更频繁地完成.
问题3:使用数组遇到的问题不是存储约定和/或不兼容问题,而是更多的性能问题.
标签:spread-syntax,javascript,redux 来源: https://codeday.me/bug/20191003/1850608.html