Redux — добавление элемента в массив, вложенный в объект внутри массива

Не могу понять, как правильно вставить элемент в массив, внутри объекта, внутри массива. Вот пример моих данных по умолчанию для структуры:

const defaultState = {
  myinbox: [
    {
      owner: 'John Lennon',
      owner_id: 1,
      read: true,
      messages: [
        {
          _id: 1,
          text: 'When will you be home?',
          createdAt: new Date(Date.UTC(2017, 10, 11, 11, 20, 0)),
          user: {
            _id: 1,
            name: 'John Lennon'
          }
        }
 ...

Я хочу добавить еще одно сообщение, когда приходит входящее сообщение. Вот как выглядит фрагмент моего редуктора:

const inboxReducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD_INBOUND_MESSAGE':
      return {
        ...state,
        myinbox: [
          state.myinbox[action.payload.index]: {
            ...state.myinbox[action.payload.index],
            messages: [
              ...state.myinbox[action.payload.index].messages,
              action.payload.msg
            ]
          }
          ...state.myinbox,
        ]
      }
  default:
    return state
  }
}

Индекс родительского «владельца» передается как индекс внутри полезной нагрузки, а новое сообщение — msg в полезной нагрузке.

Я не могу понять, как написать этот редюсер, не изменяя исходное состояние.


person RedOster    schedule 28.11.2017    source источник


Ответы (2)


Вы изменяете исходное состояние, когда устанавливаете myinbox с помощью state.myinbox[action.payload.index]:.

Похоже, вы пытаетесь установить состояние для индекса, используя вычисленные ключи свойств. Синтаксис для этого будет следующим:

    myinbox: [
      [action.payload.index]: {
        ...state.myinbox[action.payload.index],
        messages: [
          ...state.myinbox[action.payload.index].messages,
          action.payload.msg
        ]
      }
      ...state.myinbox,
    ]
person Chris Dolphin    schedule 28.11.2017

Это можно сделать с помощью Immer.

  const { index, msg } = action.payload;
  return produce(state, (draftState) => {
    draftState.myinbox[index].messages.push(msg);
  });
person Vyacheslav Sedykh    schedule 11.03.2021