2016-07-06 48 views
12

我一直在努力学习如何更好地构建我的Redux商店,并偶然发现了Dan的这一课。Redux - 为什么正常化?

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

虽然我知道如何去用这种方式正常化我的数据,我不明白它背后的动机。特别是,我有两个问题。

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

  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从部门获取订阅的待办事项。看来我对这个概念的理解有点不足。你能否详细说明一下?

+1

是的。关于你最后的问题,如果你理解你,只需要一个浅层对象而不是对象层次结构的数组就可以工作。 但是,如果您最终在数组中有* lots *项,并且您经常执行“find this id”操作,则每个数组查找都是O(N)。将您的对象放入哈希结构中,而不是使查找O(1)...显着更快。 –

+0

完美!谢谢。 –

+0

对于任何想要了解更多关于该主题的文献,您可以参考http://redux.js.org/docs/FAQ.html#organizing-state-nested-data和链接的文章。 –

回答

12
  1. “在复杂的应用程序中,我们可能拥有多个阵列,并且在不同阵列中具有相同ID的待办事项可能会不同步。”

例如,您可能有一个TODO(例如id 1),例如它同时位于“用户的TODO”列表和“Department的TODO”列表中。然后如果用户更新她的待办事项,该TODO也应该在“部门的TODO”列表中更新。如果你的数据是标准化的,TODO将在两个地方更新(嗯,实际上只有一个TODO实例可以从多个地方简单地引用)。但如果不正常,该部门将有一个陈旧的待办事项副本。

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

我认为你是对的,说实话。如果你打算正常化,那么复制一个ID列表似乎与这种努力背道而驰。

无论如何,我认为对React中的数据进行规范化的情况可能反映了一般情况下(例如在数据库中)规范化数据的情况。预先做好了一点工作,但它给你的灵活性通常是值得的。

此外,我并不总是规范我的React代码,但我发现而不是规范化最终导致我的代码随着时间的推移变得越来越慢。我只是变得没有纪律。我想这就像破窗效应。在非标准化的代码中,我只是开始将值抛入他们真正可能不应该过于方便的地方。

+0

谢谢。你能看看我的编辑吗? –

6

为什么我们需要维护一个allIds列表?为什么要保持这个额外的状态,当我们可以很容易地映射所有待办事项清单并获得它?

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

Answer thanks to markerikson

+0

但是这个推测的排序是关于什么的? 'allIds'这个名字并不完全提供上下文......如果它的确如'allIdsSortedByName'那样,它可能会偏离'规范化'的概念 – bitstrider

+0

它可能意味着像'allIdsSortedInTheOrderAUserPutThemIn'这样的概念。像'byName'这样的东西可以在运行时推断出来,但是如果有某种类型的拖放界面,那么这个顺序就是由用户自己定义的,而不是基于每个实体的任何方面。 –

相关问题