Redux - 为什么要标准化?

IT技术 javascript reactjs redux
2021-05-04 11:11:16

我一直在努力学习如何更好地构建我的 Redux 存储,并偶然发现了 Dan 的这一课。

https://egghead.io/lessons/javascript-redux-normalizing-the-state-shape#/guidelinesModal

虽然我了解如何以这种方式规范化我的数据,但我不明白其背后的动机。特别是,我有两个问题。

  1. 为什么简单的数组不够用?Dan 提到 - “在复杂的应用程序中,我们可能有多个数组,并且不同数组中具有相同 ID 的待办事项可能会不同步”。没看懂,可以举个例子吗?我从使用对象中看到的唯一好处是提高了效率,因为我们不需要映射整个数组,以防我想将某个 todo 委托给另一个 reducer。

  2. 为什么我们需要维护一个allIds列表?当我们可以轻松地映射所有待办事项列表并获取它时,为什么要维护这个附加状态?

我知道 normalizr 为我们做了这件事,但为什么我们首先要规范化?即使响应没有深度嵌套,标准化是否有意义?

编辑1:

谢谢你的回答,克里斯托弗。

让我们假设您的状态树看起来像这样

{
    user: {
        byId: {
            1: {
                id: 1,
                name: 'Buy stuff'
               }, 
            2: {
                id: 2,
                name: 'Yeah'
               }
            }
        },
        allIds: [1, 2],
        subscribedIds: [5],
    }
    department: {
        byId: {
            5: {
                id: 5,
                name: 'Sell Stuff'
            }
        },
        allIds: [5],
        subscribedIds: []
    }   
}

我没有看到在这里用对象代替数组的好处。我也可以有选择器,即使它是一个数组,也可以通过 ID 从部门中获取订阅的待办事项。看来我对这个概念的理解有点不足。你能详细说明一下吗?

2个回答
  1. “在复杂的应用程序中,我们可能有多个数组,不同数组中具有相同 ID 的待办事项可能会不同步。”

例如,您可能有一个 TODO(例如 ID 为 1),它同时位于“用户的 TODO”列表和“部门的 TODO”列表中。然后,如果用户更新了她的待办事项,该待办事项也应该在“部门的待办事项”列表中更新。如果您的数据被规范化,TODO 将在两个地方更新(好吧,实际上只有一个 TODO 实例被简单地从多个地方引用)。但如果它不规范化,该部门将有一个陈旧的待办事项副本。

  1. “为什么要保留所有 ID 的列表?”

我认为你是对的,老实说。如果您打算费心进行规范化,那么复制 ID 列表似乎与这种努力背道而驰。

无论如何,我认为在 React 中规范化数据的情况可能反映了一般化数据的情况(例如在数据库中)。前期需要付出更多努力,但它为您提供的灵活性通常是值得的。

此外,我并不总是对我的 React 代码进行规范化,但我发现规范化最终会使我的代码随着时间的推移变得更加草率。我只是变得不那么自律了。我想这就像破窗效应。在非规范化代码中,我只是开始将值扔到它们可能不应该仅仅出于方便的地方。

为什么我们需要维护一个allIds列表?当我们可以轻松地映射所有待办事项列表并获取它时,为什么要维护这个附加状态?

存储一组 ID 允许我们定义项目的顺序。虽然 JS 引擎现在有一个相当标准化的过程来迭代对象中的键,但你不应该依赖它来定义排序。

感谢markerikson的回答