如何在规范化 redux 存储中组织部分实体?



为了满足我的项目的需要,我必须在两种方式之间进行选择,以在reducer中组织实体。

情况是,API 仅返回同一对象(在本例中为汽车)的不同视图所需的数据。

因此,第一种方法是使用规范化状态存储非标准化数据,但使用选择器来避免对象具有视图不需要的数据

const store = {
entities: {
car: {
1: {
id: 1,
name: "SuperCar",
date: "1992",
constuctor: "Super Constructor",
},
2: {
id: 2,
name: "BasicCar",
date: "1987",
picture: "...",
constuctor: "Amazing Constructor",
possessors: [3,45,34]
}
},
possessors: {
/// ...
}
},
requestResult: {
car_for_list: [2],
car_for_home: [1, 2],
}
}
const getCarsForHome = state => state.requestResult.car_for_home.map(id => state.entities.car[id])

陷阱是:

  • 我不知道实体数据的一致性

我看到的第二种方法是考虑拥有一个主实体(如父类)并使用选择器来获取视图的正确数据。 主实体拥有所有视图的所有共享属性,特定实体拥有其他属性。

const store = {
entities: {
car: {
1: {
id: 1,
name: "SuperCar",
date: "1992",
car_for_home: 1, // key to get the details for home view,
},
2: {
id: 2,
name: "BasicCar",
date: "1987",
car_for_home: 2, // key to get the details for home view,
car_for_list: 2 // key to get the details for list view
}
},
car_for_home: {
1: {
id: 1,
constuctor: "Super Constructor",
},
2: {
id: 2,
constuctor: "Amazing Constructor",
}
},
car_for_list: {
2: {
id: 2,
picture: "...",
possessors: [3,45,34]
}
},
possessors: {
/// ...
}
}
}
//Selector
const getCarsForHome = state => Object.values(state.entities.car_for_home).map( car => ({ ...state.entities.car[car.id], ...car }))

陷阱是:

  • 在更新或删除的情况下很难维护存储
  • 如果视图需要显示新属性,我可能需要修改我的存储(例如:car_for_list现在需要构造函数,所以我必须将其存储在主car中)

那么,处理这个问题的最佳方法是什么?

所以你知道,这个项目很大,生产并且会扩大规模。

我会保持状态尽可能简单,并保持像第一个例子一样。Typescript 可以帮助提高数据的一致性,这是可用于帮助第一个示例的界面:

Interface Car {
id: string;
name: string;
constructor: string;
pictures?: string[];
processor?: number[];
}

保留可能不是可选属性的属性,然后在必要时解开包装,以便在应用中的任何位置处理所有情况(未定义或已设置)。这里的挑战是在选择器中保留您的类型权限,但 typescript 具有非常好的类型推断,如果您使用重新选择此库的类型是好的!

在我看来,状态不应该包含 vues 的逻辑(就像在第二种方法中一样)。当您拾取数据(如 API)时,它就像 BDD 一样。因此,第一种方法,使用选择器根据您的 vue 获取数据,对我来说是最好的解决方案。

最新更新