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?