Redux - Как добавить запись в массив в редукторе

Я застрял с этим битом и не могу продвинуться - думаю, решение простое, но я не могу понять. Я пытаюсь добавить запись в редуктор, чтобы данные в ней выглядели примерно так:

state = {
  entryId: {
    entryName: ["something", "something2", "something3" /* and so on... */]
  }
};

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

switch(type) {
  case ADD_ENTRY:
    return {
      ...state,
      [entryId]: {
        ...state[entryId],
        [entryName]: {
          [uniqueEntry]: true
        }
      }
    };
}

Любая идея, что я делаю неправильно?


person eloleon    schedule 20.06.2016    source источник
comment
Можете ли вы написать больше контекста к примеру? Например, можете ли вы указать форму действия, с которым вы работаете?   -  person Eloy Pineda    schedule 21.06.2016
comment
Я отправляю что-то вроде этого: addEntry({ entryId, entryName, uniqueEntryid })   -  person eloleon    schedule 21.06.2016
comment
Попробуйте это: ссылка   -  person mnsr    schedule 21.06.2016
comment
спасибо jzm за усилия. Я пробовал что-то подобное, но проблема в начальном состоянии/первой записи, entryId не определен. Вы можете увидеть проблему, с которой я сталкиваюсь, когда вы устанавливаете начальное состояние для пустого объекта, т.е. const state = {}; И поскольку все значения динамические, у меня не может быть другого начального состояния.   -  person eloleon    schedule 21.06.2016


Ответы (1)


Если вы пытаетесь добавить элемент в конец массива entryName, вы должны сделать:

return {
  ...state,
  [entryId]: {
    ...state[entryId],
    [entryName]: [
      ...state[entryId][entryName],
      uniqueEntry
    ]
  }
};

Распространение ES6 с массивами работает следующим образом:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const eight = 8;

const newArray = ['stuff', ...array1, 'things', ...array2, ...[7, eight], 9];
console.log(newArray); // ["stuff", 1, 2, 3, "things", 4, 5, 6, 7, 8, 9]

Ознакомьтесь с этой сутью, в которой есть пример чего-то очень похожего на то, что вы делаете.

Я нашел этот набор примеров чрезвычайно полезным. Здесь много интересного:

https://github.com/sebmarkbage/ecmascript-rest-spread

Обновлять:

Если entryName инициализируется undefined, как вы говорите в своем комментарии, вы можете сделать это:

return {
  ...state,
  [entryId]: {
    ...state[entryId],
    [entryName]: [
      ...state[entryId][entryName] || [],
      uniqueEntry
    ]
  }
};

Я думаю, что это отличный пример того, насколько болезненной может быть работа с React/redux с использованием сильно вложенной структуры данных. FWIW, мне много раз рекомендовали максимально сгладить ваше состояние.

person jaybee    schedule 21.06.2016
comment
Спасибо dannyid! Я пробовал то же самое, и проблема в том, что начальное состояние является пустым объектом, поэтому эта строка «... state [entryId] [entryName]» выдаст ошибку - person eloleon; 21.06.2016
comment
О, это важная информация! Можете ли вы обновить свой вопрос, и я обновлю свой ответ? - person jaybee; 21.06.2016
comment
Я обновлю вопрос сейчас. Кстати, я работал над своей проблемой, используя почти такой же подход, как и вы || [] - person eloleon; 22.06.2016
comment
Есть какой-то простой способ? может immutable js? - person slideshowp2; 09.01.2017
comment
@jaybee, ты сэкономил мне часы, приятель, большое тебе спасибо! - person Maxime Lafarie; 09.11.2020