我有一个API响应,其中有许多嵌套实体。我使用normalizr尽可能使redux状态保持平整。
例如,API响应如下:
{
"id": 1,
"docs": [
{
"id": 1,
"name": "IMG_0289.JPG"
},
{
"id": 2,
"name": "IMG_0223.JPG"
}
],
"tags": [
{
"id": "1",
"name": "tag1"
},
{
"id": "2",
"name": "tag2"
}
]
}
使用下面给出的模式,使用normalizr
对此响应进行规范化:
const OpeningSchema = new schema.Entity('openings', {
tags: [new schema.Entity('tags')],
docs: [new schema.Entity('docs')]
});
以下是它的外观:
{
result: "1",
entities: {
"openings": {
"1": {
"id": 1,
"docs": [1,2],
"tags": [1,2]
}
},
"docs": {
"1": {
id: "1",
"name": "IMG_0289.JPG"
},
"2": {
id: "2",
"name": "IMG_0223.JPG"
}
},
"tags": {
"1": {
"id": 1,
"name": "tag1"
},
"2": {
"id": 2,
"name": "tag2"
}
}
}
}
现在的redux状态大致如下:
state = {
"opening" : {
id: 1,
tags: [1,2],
docs: [1,2]
},
"tags": [
{
"id":1,
"name": "tag1"
},
{
"id":2,
"name": "tag2"
}
],
"docs": [
{
"id":1,
"name": "IMG_0289.JPG"
},
{
"id":2,
"name": "IMG_0223.JPG"
}
]
}
现在,如果我派发一个添加
tag
的操作,那么它会将tag
对象添加到state.tags
中,但不会更新state.opening.tags
数组。删除标签时也是同样的行为。我将
opening
、tags
和docs
保存在三个不同的reducer中。这是状态中的不一致性。我可以想到以下几种方法来保持状态的一致性:
- 我派发一个更新标签的操作,并在
tags
reducer和opening
reducer中监听它,在两个地方都相应地更新标签。 - 用标签更新打开请求返回打开响应。我可以再次派发动作来规范化响应,并以适当的一致性设置标签、打开等。