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

Javascript 如何在redux中使用对象数组更新多个对象属性?,javascript,redux,Javascript,Redux,如何使用对象和对象数组更新状态对象中的多个属性 我的状态为以下格式: { 1: { id: 1, values: [ 1, 2] }, 2: { id: 2, values: [ 1, 2] } } [ { id: 1, values: [ 3, 4] }, { id: 2, values: [ 3, 4 ] } ] 在我的reducer中,我接收数据以更新以下格式的状态: { 1: { id: 1, values: [ 1, 2] }, 2: { id: 2, values:

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

我的状态为以下格式:

{
 1: { id: 1, values: [ 1, 2] },
 2: { id: 2, values: [ 1, 2] }
}
[
 { id: 1, values: [ 3, 4] },
 { id: 2, values: [ 3, 4 ] }
]
在我的reducer中,我接收数据以更新以下格式的状态:

{
 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] }
}

我试图通过这个映射,但它将我的状态返回到一个数组中。我想将我的状态保持为对象。

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

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

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

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

在数据到达缩减器之前对其进行转换,无论是在动作、重击、传奇还是组件中

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;
}

在数据到达缩减器之前对其进行转换,无论是在动作、重击、传奇还是组件中

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;
}

action.payload.forEach
action.payload.forEach
?转换数据后,您是一次发送所有对象还是一次发送一个对象到减速器?在本例中,您可以在
'SET\u all'
'SET\u MULTIPLE'操作中一次发送所有对象,或者您可以在
'set'
操作中一次设置一个。我正在努力解决的部分是在“set\u MULTIPLE”中,如果我同时传播状态和数据,我想将状态中的值数组与数据中的值数组合并,我将只获取新的数据值。扩展状态和数据将包含任何新值并覆盖任何现有值。添加处理程序以附加到单个项上。“多个”可能很棘手,但我相信您可以弄清楚,如果您在转换数据后了解了此代码的要点,您是一次发送所有对象还是一次发送一个对象到reducer?在本例中,您可以在
'SET\u all'
'SET\u Multiple'
操作中一次发送所有对象,或者您可以在
'set'
操作中一次设置一个。我正在努力解决的部分是在“set\u MULTIPLE”中,如果我同时传播状态和数据,我想将状态中的值数组与数据中的值数组合并,我将只获取新的数据值。扩展状态和数据将包含任何新值并覆盖任何现有值。添加处理程序以附加到单个项上。多重可能很棘手,但我相信,如果您理解了这段代码的要点,您一定会明白这一点