2016-04-23 29 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认为没有任何变化。它是非常重要的,你改变每个突变的参考。 –

相关问题