我有一个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
数组 . 删除标记时也会出现相同的行为 .
我在三个不同的reducer中保留了 opening
, tags
和 docs
.
这是州内的不一致 . 我可以想到以下方法来保持国家的一致性:
-
我发送一个动作来更新标签并在
tags
reducer和opening
reducer中监听它,并随后在两个地方更新标签 . -
用标记更新打开的补丁请求返回打开响应 . 我可以再次发送操作,使响应标准化并设置标签,打开等具有适当的一致性 .
这样做的正确方法是什么 . 实体不应该观察相关实体的变化并自行进行更改 . 或者还有任何其他模式可以遵循任何此类操作 .
1 回答
首先总结一下
normalizr
的工作原理:normalizr
展平对模式定义的实体的嵌套API响应 . 因此,当您初始化GET openings
API请求时,normalizr会将响应展平并创建Reduxentities
和展平对象:openings
,docs
,tags
.您的建议是可行的,但我发现自己更新了Redux商店中的数据...我的所有API数据都保存在
entities
中,我不会改变它们;它们是vanilla后端数据......我所做的就是在状态更改API操作时执行GET
,并规范化GET
响应 .DELETE
案件有一个小例外,我一直在使用 . 我创建了自己的中间件,但我知道redux-promise-middleware很受欢迎 .在您的数据集中;当你添加一个新的
tag
时,我假设你正在制作一个APIPOST
这样做,这反过来更新了后端 . 然后,你应该做另一个GET openings
,它将更新entities
的开口及其所有嵌套模式 .当您删除
tag
时,例如tag [2],在向后端发送DELETE
请求后,您应该使实体状态中的已删除对象无效,即 .entities.tags[2] = null
再次使GET openings
更新您的normalizr实体 .