Demigodd
@Demigodd

Как обновить один элемент в массиве в Redux?

Есть массив Messages:

messages = [
  {
   _id: "111",
   text: "text1"
  },
  {
   _id: "222",
   text: "text2"
  },
]

В Redux во время экшна:

case UPDATE_MESSAGE:
  let foundIndex = state.messages.findIndex(message => message ._id == payload._id);
  state.messages[foundIndex] = payload;

    return {
    ...state,
    messages: [...state.messages]
  };

Если вот так напрямую изменить текущий объект, то выскакивает ошибк:

A state mutation was detected inside a dispatch, in the path...

Как правильнее обновить одно сообщения в массиве?
А вообще, нужно ли так делать или лучше будет после обновления вызвать метод GetAllMessage (который загружает все сообщения для текущей комнаты) через сокет для всех пользователей в текущей комнате.
Но в этом случает у других юзеров пойдет загрузка сообщений, и как-то будет не понятней почему сообщения загружаются.
  • Вопрос задан
  • 1416 просмотров
Решения вопроса 2
@i1yas
case UPDATE_MESSAGE:
  let foundIndex = state.messages.findIndex(message => message ._id == payload._id);
  state.messages[foundIndex] = payload;

    return {
    ...state,
    messages: [...state.messages]
  };

Redux ругается потому что вы мутируете исходный state. А затем зачем-то создаете новый массив.
Правильно так:
case UPDATE_MESSAGE:
  let foundIndex = state.messages.findIndex(message => message ._id == payload._id);
  const messages = state.messages[foundIndex].slice(); // .slice() создаст копию массива
  messages[foundIndex] = payload;

    return {
    ...state,
    messages
  };

Возвращать нужно новый объект (массив), в котором были сделаны изменения.
Трогать state напрямую нельзя
Ответ написан
Комментировать
0xD34F
@0xD34F
case UPDATE_MESSAGE:
  return {
    ...state,
    messages: state.messages.map(n => n._id == payload._id ? payload : n),
  };
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы