如何在扁平化的 Redux 存储中保留继承信息?
How do I retain inheritance information in a flattened Redux store?
我在 React 应用程序中使用 Redux 进行状态管理。我还打算“扁平化”任何 API 响应,以鼓励重用并减少状态树中的数据重复。我希望使用 Normalizr 来实现这一点。
我的问题是关于管理对象之间关系的首选方式 - 特别是继承类型的关系。
应用程序向 API 发出请求(后端用 Java、Spring 编写)。已定义的领域模型包括如下关系:
interface NamedThing {
int getId();
String getName();
}
interface Pet extends NamedThing {
Person getOwner();
}
class Cat implements Pet {
int getId() {
...
};
String getName() {
...
};
Person getOwner() {
...
};
int getNumberOfLivesRemaining() {
…
};
}
class Dog implements Pet {
int getId() {
...
};
String getName() {
...
};
Person getOwner() {
...
};
int getAgeInDogYears() {
…
};
}
class Person implements NamedThing {
int getId() {
...
};
String getName() {
...
};
}
对 /pets 端点的 GET 请求的响应可能如下所示:
[{
id: 1,
type: ‘cat',
name: ‘Fluffy',
owner: {
id: 1,
name: ‘Mary'
},
numberOfLivesRemaining: 9
},
{
id: 2,
type: ‘dog',
name: ‘Ralph',
owner: {
id: 1,
name: ‘Mary'
},
ageInDogYears: 10
}]
定义了正确的模式后,Normalizr 会将响应扁平化为如下内容:
{
result: [
{id: 1, schema: ‘cats’},
{id: 2, schema: ‘dogs’}
],
entities: {
cats: {
1: {
id: 1,
type: ‘cat’,
name: ‘Fluffy’,
owner: 1,
numberOfLivesRemaining: 9
}
},
dogs: {
2: {
id: 2,
type: ‘dog',
name: ‘Ralph',
owner: 1,
ageInDogYears: 10
}
},
persons: {
1: {
id: 1,
name: ‘Mary’
}
}
}
}
方法一:
不同的实体(猫、狗和人)可以存储在应用程序状态下类似命名的集合中。但是,我会丢失猫和狗是宠物的细节,自从我调用 pets 端点后我就知道了。
方法二:
我可以将所有宠物实体存储在一个宠物集合中,并将所有猫的 ID 和所有狗的 ID 存储在单独的集合中。然后,我可以通过使用 React-Redux mapStateToProps 函数进行相应的过滤,将所有的猫、所有的狗或所有的宠物传递到一个组件中。
但是,如果我向 /namedThings 端点发出 GET 请求,我将返回猫、狗和人并将它们存储在 namedThings 集合中,其中包含猫、狗和人的 ID 的集合。但是,同样,我不知道猫狗也是宠物,因为 API 响应中没有包含此信息。
为了解决这个问题,我可以:
- 更改 API 以便在响应中包含超类型信息
- 将猫和狗的集合映射到包含所有宠物的合并组件“prop”
- 让 reducers 知道猫是宠物,因此在将猫添加到商店时将 id 添加到宠物 ID 集合。
在使用 Redux 和 Normalizr 时,表示此类实体层次结构的最佳方法是什么?其他团队如何解决这个问题?
这两种方法听起来都不错:
Map both the collections for cats and dogs to a merged component “prop” that contains all pets
Have the reducers know that a cat is a pet and therefore add an id to the pet id collection when adding a cat to the store.
您应该同时尝试这两种方法,看看哪种更适合您的应用程序。
我在 React 应用程序中使用 Redux 进行状态管理。我还打算“扁平化”任何 API 响应,以鼓励重用并减少状态树中的数据重复。我希望使用 Normalizr 来实现这一点。
我的问题是关于管理对象之间关系的首选方式 - 特别是继承类型的关系。
应用程序向 API 发出请求(后端用 Java、Spring 编写)。已定义的领域模型包括如下关系:
interface NamedThing {
int getId();
String getName();
}
interface Pet extends NamedThing {
Person getOwner();
}
class Cat implements Pet {
int getId() {
...
};
String getName() {
...
};
Person getOwner() {
...
};
int getNumberOfLivesRemaining() {
…
};
}
class Dog implements Pet {
int getId() {
...
};
String getName() {
...
};
Person getOwner() {
...
};
int getAgeInDogYears() {
…
};
}
class Person implements NamedThing {
int getId() {
...
};
String getName() {
...
};
}
对 /pets 端点的 GET 请求的响应可能如下所示:
[{
id: 1,
type: ‘cat',
name: ‘Fluffy',
owner: {
id: 1,
name: ‘Mary'
},
numberOfLivesRemaining: 9
},
{
id: 2,
type: ‘dog',
name: ‘Ralph',
owner: {
id: 1,
name: ‘Mary'
},
ageInDogYears: 10
}]
定义了正确的模式后,Normalizr 会将响应扁平化为如下内容:
{
result: [
{id: 1, schema: ‘cats’},
{id: 2, schema: ‘dogs’}
],
entities: {
cats: {
1: {
id: 1,
type: ‘cat’,
name: ‘Fluffy’,
owner: 1,
numberOfLivesRemaining: 9
}
},
dogs: {
2: {
id: 2,
type: ‘dog',
name: ‘Ralph',
owner: 1,
ageInDogYears: 10
}
},
persons: {
1: {
id: 1,
name: ‘Mary’
}
}
}
}
方法一:
不同的实体(猫、狗和人)可以存储在应用程序状态下类似命名的集合中。但是,我会丢失猫和狗是宠物的细节,自从我调用 pets 端点后我就知道了。
方法二:
我可以将所有宠物实体存储在一个宠物集合中,并将所有猫的 ID 和所有狗的 ID 存储在单独的集合中。然后,我可以通过使用 React-Redux mapStateToProps 函数进行相应的过滤,将所有的猫、所有的狗或所有的宠物传递到一个组件中。
但是,如果我向 /namedThings 端点发出 GET 请求,我将返回猫、狗和人并将它们存储在 namedThings 集合中,其中包含猫、狗和人的 ID 的集合。但是,同样,我不知道猫狗也是宠物,因为 API 响应中没有包含此信息。
为了解决这个问题,我可以:
- 更改 API 以便在响应中包含超类型信息
- 将猫和狗的集合映射到包含所有宠物的合并组件“prop”
- 让 reducers 知道猫是宠物,因此在将猫添加到商店时将 id 添加到宠物 ID 集合。
在使用 Redux 和 Normalizr 时,表示此类实体层次结构的最佳方法是什么?其他团队如何解决这个问题?
这两种方法听起来都不错:
Map both the collections for cats and dogs to a merged component “prop” that contains all pets
Have the reducers know that a cat is a pet and therefore add an id to the pet id collection when adding a cat to the store.
您应该同时尝试这两种方法,看看哪种更适合您的应用程序。