我有一个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
保留在三个不同的缩减器中。
这是州内的不一致。我可以想到以下方法来保持国家的一致性:
tags
reducer和opening
reducer中监听它,并随后在两个地方更新标签。这样做的正确方法是什么。不应该让实体观察相关实体的变化并自行进行更改。或者还有任何其他模式可以遵循任何此类行动。
答案 0 :(得分:4)
首先总结一下normalizr
的工作原理:normalizr
展平对模式定义的实体的嵌套API响应。因此,当您提出初始GET openings
API请求时,normalizr会将响应展平并创建Redux entities
和展平对象:openings
,docs
,tags
您的建议是可行的,但我发现normalizr
在将API数据与UI状态分离方面确实有益;因此,我自己不会在Redux商店中更新数据......我的所有API数据都保存在entities
中,并且我不会更改它们;它们是vanilla后端数据......我所做的就是在状态更改API操作时执行GET
,并规范化GET
响应。 DELETE
案件有一个小例外,我稍后会对此进行扩展......中间件会处理此类情况,因此如果您还没有使用过,请使用一个。我创建了自己的中间件,但我知道redux-promise-middleware很受欢迎。
在您的数据集中;当您添加新的tag
时,我假设您正在制作API POST
,这样就会更新后端。然后,您应该执行另一个GET openings
,这将更新entities
的空缺及其所有嵌套模式。
删除tag
时,例如tag [2],在向后端发送DELETE
请求后,您应该使实体状态中的已删除对象无效,即。在再次entities.tags[2] = null
更新您的normalizr实体之前GET openings
。{/ p>