In React I have an array variable defined using useState, called messages. I also have a component on the page which doesn't have any DOM but rather listens for events on a websocket. When my component gets advised of an event from the websocket, the length of my messages variable is always zero - despite it having multiple messages previously. How come the array is empty at the time the function is entered?
Here's a minimal set of code which reproduces the issue:
WebSocketNotificationHandler.tsx:
import { useEffect } from "react";
import config from "../../../config.json";
import { IChatMessage } from "../../../services/chatService";
interface WebSocketNotificationHandlerProps {
onReceiveMessages: (newMessages: IChatMessage[]) => void;
}
export let client: WebSocket = new WebSocket(config.webSocketAddress, config.webSocketProtocol);
const WebSocketNotificationHandler = (props: WebSocketNotificationHandlerProps) => {
useEffect(() => {
if (client) {
client.onmessage = async (ev) => {
handleWebSocketMessage(ev);
}
}
}, []);
const handleWebSocketMessage = async (ev: MessageEvent<string>) => {
props.onReceiveMessages([]); // Simplified, normally we send one or more
}
return (
<></>
);
}
export default WebSocketNotificationHandler;
And GroupPage.tsx:
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import chatService, { IChatMessage, ICreateMessageResponse } from '../../../services/chatService';
import ChatMessage from '../../atoms/ChatMessage/ChatMessage';
import ChatStagingArea from '../../organisms/ChatStagingArea/ChatStagingArea';
import WebSocketNotificationHandler from '../../organisms/WebSocketNotificationHandler/WebSocketNotificationHandler';
const GroupPage = () => {
const { groupName } = useParams();
const [messages, setMessages] = useState<IChatMessage[]>([]);
const loadGroup = async () => {
setMessages([]);
await chatService // REST API to get current messages, returns a list >0 elements
.getGroup(groupName)
.then(data => {
setMessages([...data.data.messages]);
});
}
useEffect(() => {
loadGroup();
}, []);
const handleMessageSent = (message: ICreateMessageResponse, text: string) => {
let newMessages = [...messages, { /* Message data for a new message */ }];
setMessages(newMessages);
}
const handleNewMessages = (newMessages: IChatMessage[]) => {
console.log(messages.length); // Always 0 even if I can see multiple???
// Code goes here that adds the newMessages to the messages array
};
return (
<>
{messages && messages.map(m => <ChatMessage key={m.id} author={m.fullName} date={m.authoredDate} message={m.message} />)}
<ChatStagingArea groupName={groupName} onSent={(message, text) => handleMessageSent(message, text)} />
<WebSocketNotificationHandler onReceiveMessages={newMessages => handleNewMessages(newMessages)} />
</>
);
}
export default GroupPage;
from In React, why is my array thought to be empty in a function triggered by a websocket message?
No comments:
Post a Comment