首页 文章

Redux Normalizr:在Redux状态下添加和删除规范化实体

提问于
浏览
2

我有一个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中保留了 openingtagsdocs .

这是州内的不一致 . 我可以想到以下方法来保持国家的一致性:

  • 我发送一个动作来更新标签并在 tags reducer和 opening reducer中监听它,并随后在两个地方更新标签 .

  • 用标记更新打开的补丁请求返回打开响应 . 我可以再次发送操作,使响应标准化并设置标签,打开等具有适当的一致性 .

这样做的正确方法是什么 . 实体不应该观察相关实体的变化并自行进行更改 . 或者还有任何其他模式可以遵循任何此类操作 .

1 回答

  • 3

    首先总结一下 normalizr 的工作原理: normalizr 展平对模式定义的实体的嵌套API响应 . 因此,当您初始化 GET openings API请求时,normalizr会将响应展平并创建Redux entities 和展平对象: openingsdocstags .

    您的建议是可行的,但我发现自己更新了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 再次使 GET openings 更新您的normalizr实体 .

相关问题