2016-07-06 41 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'這樣的東西可以在運行時推斷出來,但是如果有某種類型的拖放界面,那麼這個順序就是由用戶自己定義的,而不是基於每個實體的任何方面。 –