Reputation: 211
Goal:
I'm trying to get messages from a server through a websocket connection and add them to an array of objects called outgoingMessages
.
Problem:
Only the newest message is saved in outgoingMessages
when receive()
is called.
I suspect this happens because Websocket.onmessage
only uses the value of outgoingMessages
from the time when I call connect()
. I've tried fiddling around with it quite a bit, but I haven't been able to fix this issue.
How can I get receive()
to use the current state, not the initial one?
Thanks in advance.
const Dashboard = () => {
const [incomingMessages, setIncomingMessages] = React.useState([]);
const ws = React.useRef(null);
const receive = (message) => {
setIncomingMessages([...incomingMessages, message]);
};
const connect = () => {
ws.current = new WebSocket(WS_URL + "mqtt/ws/messages");
ws.current.onopen = () => setWsConnected(true);
ws.current.onclose = () => setWsConnected(false);
ws.current.onmessage = (event) => receive(event);
};
return (<>Stuff</>)
}
Upvotes: 1
Views: 1539
Reputation: 13692
Looks like the connect
function is called once in the initial render and in the receive
function, the incomingMessages
value is always obtained from the closure
and hence you only see the latest message.
To set state, use functional set state pattern i.e provide a callback to setIncomingMessages.
Like this
const Dashboard = () => {
const [outgoingMessages, setOutgoingMessages] = React.useState([]);
const ws = React.useRef(null);
const receive = (message) => {
setIncomingMessages(prev => [...prev, message]);
};
const connect = () => {
ws.current = new WebSocket(WS_URL + "mqtt/ws/messages");
ws.current.onopen = () => setWsConnected(true);
ws.current.onclose = () => setWsConnected(false);
ws.current.onmessage = (event) => receive(event);
};
return (<>Stuff</>)
}
p.s. -- just a quick note - your state deals with outgoingMessages
but you do set state for incomingMessagesin
receive` fun. So have a check on that...
Upvotes: 5