Gau*_*mar 3 redux normalizr react-redux redux-actions
我有一个包含很多嵌套实体的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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
normalizr使用以下给出的模式对该响应进行规范化:
const OpeningSchema = new schema.Entity('openings', {
tags: [new schema.Entity('tags')],
docs: [new schema.Entity('docs')]
});
Run Code Online (Sandbox Code Playgroud)
下面是它的外观:
{
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"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我分派一个动作来添加tag,那么它会添加一个tag对象,state.tags但不会更新state.opening.tags数组。删除标签时也具有相同的行为。
我保留opening,tags并docs使用三种不同的减速器。
这是一个不一致的状态。我可以想到以下几种保持状态一致的方法:
tagsreducer和openingreducer中监听它,并随后在两个地方更新标签。什么是正确的方法来做到这一点。实体不应该观察相关实体的更改并自行进行更改。或者,任何其他模式都可以遵循任何此类操作。
小智 5
首先总结一下normalizr工作原理:将normalizr嵌套API响应展平到您的模式定义的实体。所以,当你做了最初的GET openingsAPI请求,normalizr扁平响应,并创建了终极版entities和扁平对象:openings,docs,tags。
您的建议是可行的,但我发现normalizr将API数据与UI状态分开确实有好处。因此,我自己不会更新Redux存储中的数据。我的所有API数据均保存在其中,entities并且它们不会被我更改;它们是原始的后端数据...我要做的就是GET根据状态更改API操作并标准化GET响应。对于DELETE案例,有一个小例外,我将在以后进行扩展...中间件将处理此类案例,因此如果您没有使用过,则应使用其中一种。我创建了自己的中间件,但是我知道redux-promise-middleware很受欢迎。
在上面的数据集中;当您添加一个新的时tag,我假设您正在创建一个API POST来这样做,这反过来又更新了后端。然后,您应该执行另一个操作GET openings,该操作将更新entitiesfor开口及其所有嵌套模式。
当您删除tag,例如tag [2]时,在将DELETE请求发送至后端时,应在实体状态(即)中使已删除的对象无效。entities.tags[2] = null在GET openings再次更新您的normalizr实体之前。
| 归档时间: |
|
| 查看次数: |
2108 次 |
| 最近记录: |