2016-06-22 76 views
20

鑑於我最初Redux的狀態是:陣營 - 終極版複合體(深)狀態的對象

const state = { 
    currentView: 'ROOMS_VIEW', 
    navbarLinks: List([ 
    {name: 'Rooms', key: 'ROOMS_VIEW'}, 
    {name: 'Dev', key: ''} 
    ]), 
    roomListsSelected: {group: 0, item: 0}, 
    roomLists: [ 
    { 
     name: "Filters", 
     expanded: true, 
     listItems: [ 
     { icon: 'images/icon-warning.svg', name: 'Alerts', filter: room => room.hasAlert }, 
     { icon: 'images/icon-playlist.svg', name: 'In Progress', filter: room => room.progress > 20 }, 
     { icon: 'images/icon-playlist.svg', name: 'Almost Done', filter: room => room.progress > 90 }, 
     { icon: 'images/icon-playlist.svg', name: 'Complete', filter: room => room.status === 'complete' }, 
     { icon: 'images/icon-playlist.svg', name: 'Recently Completed', filter: room => false }, 
     { icon: 'images/icon-playlist.svg', name: 'All Rooms', filter: room => true } 
     ] 
    } 
    ], 
    rooms: List(generateRooms()) 
} 

我需要一個減速,這是否:

state.roomList[n].expanded = !state.roomList[n].expanded 

我是新來使用終極版工作流程和解決此問題的最佳方法是將roomList作爲immutable.js對象或編寫一些代碼以對我的狀態對象進行深層克隆。

此外,state.roomList將從未來的功能中推送新的數據。

總結/問題:當在狀態較深的狀態下進行更改時,還原器中返回新狀態對象的最佳方式是什麼?還是應該更改Redux狀態對象的結構?

我做了什麼最終Immutable似乎是要走的路。使用Immutable有一些技巧可以減少反應渲染時間並滿足所有項目要求。此外,在項目中使用新的庫並不做重大更改已經足夠早了。

+0

您有問題要問? –

+1

當在狀態較深的狀態下進行更改時,還原器中返回新狀態對象的最佳方法是什麼?還是應該更改Redux狀態對象的結構? –

回答

27

首先,慣用的Redux鼓勵你「規範化」你的狀態,並儘可能地將它變平。使用按項目ID鍵入的對象可以直接查找項目,使用ID數組來表示排序,以及一個項目需要引用另一個項目的任何位置,它僅存儲其他項目的ID而不是實際數據。這使您可以更簡單地查找和更新嵌套對象。見the Redux FAQ question on nested data

此外,它看起來像你目前直接存儲在你的Redux狀態的一些功能。 從技術上來說可以工作,但絕對不是慣用的,會打破時間旅行調試等功能,因此非常不鼓勵。 Redux FAQ給出了更多關於why storing non-serializable values in your Redux state is a bad idea的信息。

編輯:

作爲後續,我最近增加了一個新的部分到終極版文檔,對"Structuring Reducers"的話題。特別是,本節包括有關"Normalizing State Shape""Updating Normalized Data"以及"Immutable Update Patterns"的章節。

+1

這似乎是最「正確的」答案,並且將狀態函數存儲在狀態中是一個快速修復,在發佈前將更改爲更傳統的方法。 –

+0

當然。您可能會考慮的一種相關方法是在您的狀態中存儲某種過濾器名稱或標識符,然後將其用作查找組件或選擇器中的實際過濾器函數的鍵,類似於管理對話框組件所建議的方法在http://stackoverflow.com/questions/35623656/how-can-i-display-a-modal-dialog-in-redux-that-performs-asynchronous-actions/。 – markerikson

+1

例如,很棒的 – Green

6

減速機構成: 將減速機拆成小塊,以便減速機足夠小,可以處理簡單的數據結構。例如。在你的情況下,你可能有:roomListReducerlistItemsReducerlistItemReducer。然後在每個縮減器處,它將使您更容易閱讀您正在處理的狀態的哪一部分。它有很大的幫助,因爲你的每個reducer都在處理一小部分數據,你不必擔心像'我應該深拷貝還是淺拷貝'。

不可變 我個人不使用immutable.js,因爲我更喜歡處理普通對象。並且有太多的代碼需要改變才能採用新的API。但想法是,確保你的狀態改變總是通過純函數完成的。因此,您可以簡單地編寫自己的幫助函數來執行所需的操作,只要確保在處理複雜對象時對它們進行了徹底測試。或者乾脆就可以在每個reducer中深度複製你的狀態,並在複製中進行mutate,然後返回副本。但這顯然不是最好的方法。

+2

combineReducers文檔:http://redux.js.org/docs/api/combineReducers.html –

+0

@StevenBayer我錯過了一些重要的事情嗎? – xiaofan2406

+1

隨着解構我的減速器我仍然結束了複雜的對象,他們只是稍微嵌套。沒有重要的錯過,只是一個有用的鏈接,因爲別人googles這個問題。 –