2016-04-23 88 views
1

我正在Redux商店上創建新的操作。 我有一個項目列表,所有項目都有「overlayVis」屬性。我想將所有這些設置爲true,除了指定的ID。我目前的實施方案是對redux reducer中的數組進行多次更新

case ITEM_OVERLAY_TOGGLE: 
    // object to be updated and returned 
    var returnObj = state.data; 

    state.data.map((item) => { 
    if (item.id === action.id) { 
     returnObj = Object.assign({}, ...state, { 
     data: [ 
      ...state.data.slice(0, item.id), 
      Object.assign({}, ...state.data[item.id], {overlayVis: false}), 
      ...state.data.slice(item.id + 1)] 
     }); 
    } else if (!item.overlayVis) { 
     returnObj = Object.assign({}, ...state, { 
     data: [ 
      ...state.data.slice(0, item.id), 
      Object.assign({}, ...state.data[item.id], {overlayVis: true}), 
      ...state.data.slice(item.id + 1)] 
     }); 
    } 
    }); 

    return returnObj; 

每次迭代都將覆蓋上一次迭代,因此每次運行操作時只進行一次更改。我試圖使用「狀態」和「returnObj」而不是「...狀態」,但它沒有奏效。我很長一段時間沒有在這裏發佈,但我沒有想法。

任何幫助將不勝感激!

回答

0

我認爲你的地圖功能可以改變看起來像這樣。我只能從這裏猜測,但你能否看到這是否有效?

映射函數用於變換數組中的對象,並且您需要返回映射函數中的值以使變換髮生。轉換後的值存儲在一個名爲newData的新數組中。那是在外面回來的。

case ITEM_OVERLAY_TOGGLE: 
    var newData = state.data.map((item) => { 
    if (item.id === action.id) { 
     return { 
      ...item, 
      overlayVis:false 
     } 
    } else { 
     return { 
       ...item, 
       overlayVis : true 
     } 
    } 
    }); 

return { 
    ...state, 
    data: newData 
    } 

編輯:如果action.id也是數組的索引,試試這個

case ITEM_OVERLAY_TOGGLE: 
    // object to be updated and returned 

    return { 
    ...state, 
    data : [ 
     ...state.data.slice(0,action.id).map(i=>{ i.overlayVis = true, return i; }), 
     state.data[action.id].overlayVis=false, 
     ...state.data.slice(action.id+1).map(i=>{ i.overlayVis = true, return i; }) 
    ] 
    }; 
+0

我想我只是靈光一現...事情似乎更加清晰!謝謝,似乎完美地工作。 – Oli

+0

但是等等......這會再次從零開始重新創建所有項目? – Oli

+0

是的,它的確如此。但是如果你不這樣做,你的React組件所持有的引用將保持不變,這意味着Component認爲沒有任何變化。它是非常重要的,你改變每個突變的參考。 –

相關問題