Redux - 为什么要正常化?

时间:2016-07-06 10:55:31

标签: javascript reactjs redux

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

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

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

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

  2. 为什么我们需要维护allIds列表?当我们可以轻松地映射所有待办事项列表并获取它时,为什么要保持这种额外状态呢?

  3. 我知道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 个答案:

答案 0 :(得分:14)

  1. "在复杂的应用程序中,我们可能有多个阵列,并且不同阵列中具有相同ID的待办事项可能会不同步。"
  2. 你可能有一个TODO(比如id 1),它位于"用户的TODO"列表和部门的TODO"例如,同时列出。然后,如果用户更新她的待办事项,那么该TODO也应该在部门的TODO"名单。如果您的数据被标准化,TODO将在两个地方更新(嗯,实际上只有一个TODO实例,它只是从多个地方引用)。但如果它没有正常化,该部门将有一个陈旧的待办事项副本。

    1. "为什么要保留所有ID的列表?"
    2. 老实说,我认为你是对的。如果你打算进行规范化,那么复制一份ID列表似乎与这种努力背道而驰。

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

      另外,我并不总是规范化我的React代码,但我发现 not 规范化最终导致我的代码随着时间推移变得更加笨拙。我变得不那么自律了。我想这就像破窗效应一样。在非规范化代码中,我只是开始将值放到他们可能不应该仅仅是出于方便的地方。

答案 1 :(得分:8)

  

为什么我们需要维护allIds列表?当我们可以轻松地映射所有待办事项列表并获取它时,为什么要保持这种额外状态呢?

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

Answer thanks to markerikson