Reputation:
I am creating a chat app in react
, expressjs
and socket.io
. When I click on Send Button, I am emitting an event and listening that event on server side and again emitting another event from server side and listening that event on client side. And I have written the event listening code on componentDidMount
. But don't know why my client side calling same event multiple times. Below is my both side code:
Client side
var socketIOClient = require('socket.io-client')('http://localhost:4001');
sendMessageClicked(e) {
e.preventDefault();
let message = this.state.originalMessage;
var data = {
message: message,
time: Date.now()
}
socketIOClient.emit('send_message',data);
}
componentDidMount() {
socketIOClient.on('msg',function(result){
let messageHtml = 'messages working!';
let messageBox = document.getElementById('messageBox');
if (messageBox ) {
messageBox.appendChild(messageHtml);
}
})
}
render(){
return(
<div>
<form onSubmit={this.sendMessageClicked}>
<textarea onChange={this.handleMessageChange} name="originalMessage" value={this.state.originalMessage}></textarea>
<input type="submit" value="" />
</form>
</div>
);
}
Server side
const app = require('./app');
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4001);
io.on('connection',function(socket){
socket.on('send_message',function(data){
io.emit('msg',data);
})
})
Can anyone please help with the same?
Upvotes: 2
Views: 2089
Reputation: 633
In the useEffect()
hook, checking if socket connection already exists using socket.current
helped me get rid of this problem -
useEffect(() => {
(async () => {
if (!socket.current) {
socket.current = io(`http://localhost:8080/`)
.on("connect", () => {
//do something
});
socket.current.on("message", (instance) => {
//receive message from server
});
}
})();
});
Upvotes: 1
Reputation: 31
I had the same issue, and I solved it with useEffect hook. in your case it would be (on client side):
useEffect(()=>{
socket.on('msg', (result) => {
let messageHtml = 'messages working!';
let messageBox = document.getElementById('messageBox');
if (messageBox ) {
messageBox.appendChild(messageHtml);
})
return function cleanup() {socket.off('msg')}
},[])
I'm sure you could do this also with ComponentDidUpdate or ComponentDidUnmount, but useEffect is eassier.
Upvotes: 3