In my react app, I initialize a connection with the backend socket Io server. Inside the server, I console.log
the socket that has connected, and everything works as expected, the client connects fine.
However, after connecting, the server emits an event, and on the client I am listening to this event, however the listener is not being fired.
Here is the client:
import io from "socket.io-client"
const socket = io.connect("http://localhost:5000")
const Home = () => {
const [welcome, setWelcome] = useState("")
useEffect(() => {
socket.on("welcome", (data) => {
// This code here never gets executed
console.log("hit")
setWelcome(data)
})
return () => socket.off("welcome")
}, [socket])
return (
<>
{welcome}
</>
)
And here is the server code for the socket:
const io = new Server(httpServer, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
},
})
io.on("connection", (socket) => {
socket.emit("welcome", "Hello")
// The console log logs the socket id as expected
console.log(`User connected: ${socket.id}`)
})
I would like to add that the code inside socket.on(welcome)
does get executed one time when the page first loads, however after a page refresh, the code never gets executed. The server still logs a new connection after a page refresh, however the on("welcome")
listener doesn’t get fired.
Why is the react code not firing the socket listener? Thanks.
2
Answers
I can’t comment because I lack of reputation. Does the previous connection closes on page refresh? (because it should). On server side, you could check with something like
However, the issue is in the frontend, because you say that a new connection is logged when page refresh is performed. You could try to debug your useEffect to see if the socket instance is actually being created with
console.log(socket)
:The only reason you aren’t receiving the event on client side is because there isn’t a listener, so your socket instance is the issue. It seems that the useEffect cleanup is executed and the event listener is removed and never created again.
By the way, if you are building a websocket-based app, there isn’t a problem if you connect the socket on page load or component mount. But if your app will use sockets only on certain sections, you should create the socket instance and then connect and disconnect when your app needs to.
@Herb adams – I suspect you are not running your local on port 3000. Two, the way you try to use socket as dependency is not correct in your client code. React doesnt rerender when there is mutation on variable declared ouside component. And three the return callback to socket off is bad code, check this link 1 remarks about cleanup in useEffect
Note – with my below code server is running port 3000 and client running on port 3001
server code:
**client code: **
link 2- how to use socket.io in react