2016-08-18 71 views
1

我正嘗試在React/Redux中創建一個航班搜索應用程序,在主屏幕中顯示我的所有航班結果,並在側邊欄中顯示不同類型的過濾器顯示覆選框。 (作爲例子,請參見this example在反應中更新深嵌套狀態(規範化)

該濾波器由類型分組,例如出發站,到達站等在一個規範化的嵌套狀態,其中每個元素具有以下性質中創建的所有filterelements離開時間:

"type": "airlines",   // this is the group type 
"checked": true,    // will be switched true or false 
"label": "Brittish Airways" // this is the display label 

當我點擊我的陣營視圖複選框中的一個,下面的動作將被解僱:

export function filterFlightOffers(item, index) { 
    return { 
     type: 'FILTER_FLIGHT_OFFERS', 
     grouptype, 
     id 
    } 
} 

我想我的終極版減速器更新狀態(開關檢查值),並返回新的狀態(例如,我mmutable)。在網上查看例子,我反應瞭解決方案,例如用擴展運算符複製新狀態,例如, ...狀態並用切換的選中項目更新spefic元素,例如, {[action.id]:選中,!選中}。

但我只是不能得到它的工作,我認爲由於我有一個深層嵌套狀態的事實。因此,我刪除了行動和減速器的複雜性,並做了一個簡單的jsfiddle應該只是console.log一個新的不可變'改變'狀態。

有人可以幫助我嗎?

http://jsfiddle.net/gzco1yp7/4/

謝謝!

+0

爲什麼在'state [action.id]'裏面嵌套'... state [action.id]'?如果你能解釋你的行爲和你想要做什麼,那麼幫助會更容易一些。例如,也許你正在嘗試用'action.exercise'更​​新'action.id'練習。你在這裏所擁有的和你在小提琴中的狀態根本不符合。 – ajmajmajma

+0

O,我真的很抱歉。顯示在應用程序中的代碼與我的真實代碼無關。它只是一個在線例子的副本,顯示了principe。我正在處理的代碼在小提琴中。爲了使事情更容易,我已經刪除了整個行動。只有尋找解決方案才能複製初始狀態並更新其中的特定深層元素......我將相應地更新我的初始問題。 – user3611459

+0

不用擔心,這兩個例子之間沒有清晰的圖片顯示你正在嘗試做什麼。如果你能清楚地描述你在狀態中想要改變的是什麼,以及如何(例如你將行爲傳遞給你的減速器),我可以告訴你如何用不變的方法來實現它... – ajmajmajma

回答

1

如果你的狀態看起來是這樣的:

{  
    result: [1,2,3,4], 
    entities: { 
    searchitems: { 
     1: { 
     "type": "matchAirlines", 
     "checked": false, 
     "label": "Match airlines" 
     }, 
     2: { 
     "type": "airlines", 
     "checked": true, 
     "label": "Air France" 
     }, 
     3: { 
     "type": "airlines", 
     "checked": true, 
     "label": "Brittish Airways" 
     } 
    }, 
    counts: 
     1: { "count": 2001 }, 
     2: { "count": 579 }, 
     3: { "count": 554 } 
    } 
    } 
} 

...你減速看起來是這樣的:

function reducer(state, action) { 

    switch (action.type) { 
    case 'FILTER_FLIGHT_OFFERS': 
     return { 
     ...state, 
     entities: { 
      ...state.entities, 
      searchItems: Object.keys(state.entities.searchItems).reduce((newItems, id) => { 
      const oldItem = state.entities.searchItems[id]; 
      if (oldItem.type === action.groupType) { 
       newItems[id] = { ...oldItem, checked: id === action.id }; 
      } else { 
       newItems[id] = oldItem; 
      } 
      return newItems; 
      }, {}) 
     } 
     }; 
    } 

    return state; 
} 

如果使用combineReducers,並創建一個減速只是這更簡單你的searchItems。並且lodash也可以簡化:

import mapValues from 'lodash/mapValues'; 

function searchItemsReducer(state, action) { 

    switch (action.type) { 
    case 'FILTER_FLIGHT_OFFERS': 
     return mapValues(state, (oldItem, id) => (
     oldItem.type === action.groupType 
      ? { ...oldItem, checked: id === action.id }; 
      : oldItem 
    )); 
    } 

    return state; 
} 
+0

Thnx,特別是第二條建議讓我覺得......爲什麼不讓我的狀態變得更容易呢?我轉換爲一個簡單的對象數組,現在可以使用.map和.filter來使事情發揮作用。非常感謝您的回答! – user3611459