I'm trying to design a chat application using sockets in react. Whenever a new_message
event is triggered from backend, I'm trying to append that message in the exisiting messages array, but seems like that ain't working.
Here's the code what I tried:
useEffect(() => {
socket.on("new_message", (data) => { // receving the event and appending the new message in the existing array of messages.
setConversation([...conversation, data.message]);
});
});
useEffect(() => {
socket.emit("join_room", lead._id);
if (lead._id !== undefined) {
getConversationByRoomId(lead._id).then(({ data }) =>
setConversation(data.conversation)
);
}
}, [lead]);
const handleKeyPress = async (e) => {
if (e.key === "Enter") {
await postMessage(lead._id, { messageText: message }); // API which will save this message in the database and triggers an event called new_message to the socket
setMessage("");
}
};
Somehow, it's only adding the new message in the conversation array and removes all the other conversation. What can be done to resolve this ?
CodePudding user response:
With the info you have given in your question, I think the first to change and observe would be the way socket.on
is implemented. I wouldn't bind a new event handler every time a state update happens and that too without removing the previous one in a cleanup function.
Try doing it the following way by taking advantage of state updator function :-
useEffect(() => {
socket.on("new_message", (data) => {
setConversation(prevConversation=>[...prevConversation, data.message]);
});
},[]);
Also make sure that getConversationByRoomId
is actually returning the whole conversation
array as you intend to by logging it's value before setting the same in state.