#javascript #redux #react-redux #immutability
#javascript #redux #реагировать-redux #неизменность
Вопрос:
У меня есть массив комнат чатов, в каждой комнате есть свойство массива сообщений.
// state
const INITIAL_STATE = {
myRooms: {
rooms: [],
isLoading: false,
isLoaded: false,
isError: false,
},
};
Комната и ее элементы определяются как
{
"creator": {
"username": "LangCodex"
},
"joiner": {
"username": "Bingo"
},
"date_created": "2020-10-04T19:23:01.380918",
"messages": [],
"name": "9496dd0a223f712f4a9d2f3fba4a0ab0",
"status": "offline"
}
Сообщение и его элементы определяются следующим образом:
{
"author": {
"username": "Bingo"
},
"recipient": {
"username": "LangCodex"
},
"body": "hello",
"date": "2020-10-07T11:11:25.828269",
"id": 602,
"room": "9496dd0a223f712f4a9d2f3fba4a0ab0",
"seen": false,
"type": "text"
},
Мой редуктор определен, как показано ниже, и он получает данные типа String (roomName), с помощью которых я выбираю комнату, для свойств просмотра сообщений которой должно быть установлено значение true.
case 'MARK_CHAT_AS_READ': {
const roomIndex = state.myRooms.rooms.findIndex(r => r.name === action.payload.roomName);
// magic happens here
return {...state}
}
Я уже давно борюсь с этим. Любая помощь будет высоко оценена.
Редактировать: то, что я пытаюсь сделать, это установить свойство ‘seen’ для каждого сообщения комнаты (индекс которого возвращается roomIndex) в значение true.
Комментарии:
1. можете ли вы подробнее рассказать, чего именно вы хотите достичь здесь?
2. @MAS, извините, это было недостаточно ясно, я добавил небольшое объяснение того, что я пытаюсь сделать.
Ответ №1:
Что-то вроде этого должно сработать
case 'MARK_CHAT_AS_READ': {
return {
...state, // copy state
myRooms: {
...state.myRooms, // copy myRooms
rooms: state.myRooms.rooms.map(room => { // create new rooms array
// keep room untouched if the name is different
if (room.name !== action.payload.roomName) return room;
return { // create new room
...room,
// with new messages array, containing updated values
messages: room.messages.map(message => ({...message, seen: true}))
};
}),
}
}
}
НО. Вам следует лучше нормализовать структуру redux и использовать immer, чтобы избежать вложенных обновлений.
Комментарии:
1. Это сделало свое дело, спасибо за ответ, а также за предложение. с благодарностью, @Tarabanko