在“ 设计状态形状 ”一章中,文档建议将状态保留在以ID为键的对象中:
将每个实体保留在以ID作为键存储的对象中,并使用ID从其他实体或列表中引用它。
他们继续陈述
将应用程序的状态视为数据库。
我正在处理状态列表中的过滤器列表,其中一些将处于打开状态(它们显示在弹出窗口中),或者具有选定的选项。当我阅读“将应用程序的状态视为数据库的情况”时,我想到了将其视为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',
}
}
从理论上讲,只要数据可序列化(在“状态”标题下)就没有关系。
因此,我快乐地使用了对象数组方法,直到编写减速器为止。
使用对象按ID的方法(以及对扩展语法的自由使用),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)减速器的简单性是采用对象按键输入方法的动力吗?该状态形状还有其他优点吗?
和
2)似乎ID的对象键输入方法使处理API的标准JSON输入/输出变得更加困难。(这就是为什么我首先使用对象数组的原因。)因此,如果您采用这种方法,是否只是使用一个函数在JSON格式和状态形状格式之间来回转换呢?看起来笨拙。(尽管您提倡使用这种方法,但您的推理的一部分是否比上面的对象数组化简器笨拙?)
和
3)我知道Dan Abramov将Redux设计为在理论上与状态数据结构无关(如“按惯例建议,顶级状态是对象或其他一些键值集合,例如Map,但从技术上讲,它可以是任何类型 ”)。但是,鉴于上述情况,是“推荐”将其保留为以ID为键的对象,还是通过使用一系列使它成为对象的对象而遇到其他无法预见的痛点,所以我应该中止该操作计划并尝试坚持使用以ID为键的对象?
sort_by
?const sorted = _.sortBy(collection, 'attribute');