on my root component I am setting up the the socket like this,
const [socket, setSocket] = useState(null);
const setupSocket = () => {
const token = localStorage.getItem('CC_Token');
if (token && token.length > 0 && !socket) {
const newSocket = io('http://localhost:8000', {
query: {
token: localStorage.getItem('CC_Token'),
},
});
newSocket.on('disconnect', () => {
setSocket(null);
setTimeout(setupSocket, 3000);
makeToast('error', 'Socket disconnected!');
});
newSocket.on('connect', () => {
makeToast('success', 'Socket Connected');
});
setSocket(newSocket);
}
};
useEffect(() => {
setupSocket();
}, []);
and using react-router I am passing the socket instance as a prop.
<Route
exact
path="/chatroom/:id"
render={() => <ChatroomPage socket={socket} />}
/>;
it works fine until, I refresh the page. when I refresh the page socket gets back to its initial state (null) so that, I can not send any message.
This snippet is from CharoomPage
component.
React.useEffect(() => {
if (socket) {
socket.emit("joinRoom", {
chatroomId,
});
}
return () => {
//Component Unmount
if (socket) {
socket.emit("leaveRoom", {
chatroomId,
});
}
};
//eslint-disable-next-line
}, []);
On page refresh socket is null, so It can not emit the joinRoom
event.
How can I implement this so that on page refresh I emit the joinRoom
event?
Well if you refresh the page, socket will go back to initial state null
and the useEffect
should run.
But your ChatRoomPage useEffect do not take socket
into the second arguments.
Try with
const ChatRoom = ({socket}) => {
useEffect(() => {
if( !socket) return;
socket.emit("joinRoom", {chatroomId});
return () => {
if (!socket) return;
socket.emit("leaveRoom", {chatroomId});
};
}, [socket]); //<== here
};
The strange part of your bug is that it sometime works before refresh.