如何在Redux中使用对象数组更新多个对象属性?

时间:2018-10-31 19:17:17

标签: javascript redux

如何使用对象数组和对象数组更新状态对象中的多个属性?

我的状态采用以下格式:

{
 1: { id: 1, values: [ 1, 2] },
 2: { id: 2, values: [ 1, 2] }
}

在我的化简器中,我以这种格式接收数据以更新状态:

[
 { id: 1, values: [ 3, 4] },
 { id: 2, values: [ 3, 4 ] }
]

我希望能够将来自进入减速器的对象的值添加到状态中匹配的对象值。

我想结束:

{
 1: { id: 1, values: [ 1, 2, 3, 4] },
 2: { id: 2, values: [ 1, 2, 3, 4] }
}

我试图通过此映射,但是随后它将我的状态返回到数组中。我想保持状态为对象。

2 个答案:

答案 0 :(得分:2)

地图解决方案几乎是正确的!我建议改用forEach,并且不返回任何内容,而应通过state访问id的副本并修改这些值(确保深度克隆状态以避免突变) 。然后返回新状态:

const myReducer = (state, action) => {
  const newState = someDeepCloneFunction(state);
  action.forEach(obj => {
    newState[obj.id] = obj.values
  })
  return newState
}

答案 1 :(得分:2)

在数据到达减速器之前进行转换,无论它是处于动作,重击,传奇还是组件中。

const transform = (data = []) => {
    const mappedData = {};
    data.forEach(item => mappedData[item.id] = item);
    return mappedData
}

// ...
data = transform(data)

这可以使减速器逻辑更整洁

const myReducer = (state = {}, { type, data = {}, id, values = [] }) => {
    case 'SET_ALL':
        return data;
    case 'SET_MULTIPLE':
        return {
            ...state,
            ...data
        };
    case 'SET':
        return {
            ...state,
            [id]: values
        };
    case 'APPEND_VALUES':
        return {
            ...state,
            [id]: { 
                ...state[id], 
                values: [...state[id].values, ...values] 
            }
        }
    default:
        return state;
}