【发布时间】:2021-01-18 07:51:19
【问题描述】:
我正在做一个聊天服务。
一切正常,期待以下功能:
- 当有新消息出现时,我希望更新聊天室列表(左侧)。新消息的聊天室应该移动到第一个位置。但是,组件不会自动检测到更改。我需要点击列表进行更新。
为此,我尝试了以下减速器:
case NEW_CHAT_MESSAGE:
const setRoomFirst = (array, roomId) => {
const chatIndex = array.findIndex((arr) => arr._id === roomId);
array.push(...array.splice(0, chatIndex));
return { arr: array, hasBeenUpdated: chatIndex !== -1 };
};
const rooms = state.rooms;
// move room to first position
const updatedRooms = setRoomFirst(rooms, action.payload.message.chatRoom);
if (updatedRooms.hasBeenUpdated) {
// will always be the first room
updatedRooms.arr[0].messages.push(action.payload.message);
}
return { ...state, rooms: updatedRooms.arr };
default:
return state;
}
将管理聊天状态的组件:
function Chat() {
const classes = useStyle();
const dispatch = useDispatch();
const callback = useCallback(
(rooms) => {
console.log("dispatch");
dispatch(newChatMessage(rooms));
},
[dispatch]
);
const { roomId } = useParams();
const rooms = useSelector(ChatRoomsSelector);
const [selectedRoom, setSelectedRoom] = useState(
roomId || (rooms.length ? rooms[0]._id : null)
);
const oldRoomsValue = usePrevious(rooms);
useEffect(() => {
console.log("rooms has changed", rooms);
if (!selectedRoom) {
setSelectedRoom(roomId || (rooms.length ? rooms[0]._id : null));
}
if (oldRoomsValue !== rooms) {
console.log("a change in rooms has been detected");
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rooms]);
const onSelect = useCallback((roomId) => {
setSelectedRoom(roomId);
}, []);
const current = rooms.filter((room) => room._id === selectedRoom)[0];
return (
<Container>
<Typography variant="h1" className={classes.title}>
Messagerie
</Typography>
<Grid container spacing={2}>
<Grid item xs={4}>
<ChatListContainer
rooms={rooms}
roomSelected={selectedRoom}
onSelect={onSelect}
/>
</Grid>
<Grid item xs={8}>
{current && <ChatContentContainer room={current} />}
</Grid>
</Grid>
</Container>
);
}
export default Chat;
提前感谢您的帮助! :)
【问题讨论】: