我有一个聊天室数组,每个聊天室都有一个message数组属性。
// 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"
},
我的reducer定义如下,它接收的是String(roomName)类型的数据,通过它我可以选择将其邮件的seeed属性设置为true的房间。
case 'MARK_CHAT_AS_READ': {
const roomIndex = state.myRooms.rooms.findIndex(r => r.name === action.payload.roomName);
// magic happens here
return {...state}
}
我已经为此苦苦挣扎了一段时间了。任何帮助将不胜感激。
编辑: 我想做的是将房间的每条消息(其索引由roomIndex返回)的“ seen”属性设置为true。
答案 0 :(得分:3)
类似的事情应该可以解决问题
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}))
};
}),
}
}
}
但是。您最好normalize redux structure和use immer,以避免嵌套更新。