Given the following React functional component:
const DataLog: FC = (props) => {
const [events, setEvents] = useState<string[]>([]);
const pushEvent = (event: string) => {
const updatedEvents = [...events];
updatedEvents.push(event);
setEvents([...updatedEvents]);
};
useEffect(() => {
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(
'http://localhost:9000'
);
socket.on('connect', () => {
console.log('Web socket connected');
});
socket.on('event1', (event: string) => {
pushEvent(event);
});
socket.on('event2', (event: string) => {
pushEvent(event);
});
}, []);
return (
<div>
{events.map((event: string, index: number) => {
return <div key={index}>{event}</div>;
})}
</div>
);
};
export default DataLog;
I would like to update the events
state variable each time an event1
or event2
message is received via the socket.io websocket connection. This works fine if the messages are coming in reasonably spaced out, but the issue arises when event1
and event2
, or multiple event1
or event2
messages come in very rapidly. The state update doesn't have enough time to complete before the next event is being processed resulting in the events
array being overwritten by the last call to setEvents
. Is there a way I can ensure each new message gets added to the events
state object? Do I need to manually batch state updates? Is there another hook I can use to preserve state between updates?