Problem
Hi everyone, I am trying to create a realtime messaging application. I used useState and useEffect to keep track of when I want components to re-render. However, the problem I am running into is infinite loops inside my useEffect. I'm wondering if someone can push me in the right direction on how to solve this issue without using setState inside useEffect so I can avoid infinite loops.
Things I have tried
- useRef but realized it wouldn't trigger re-renders in dependency array
- solutions from this questions: Can I set state inside a useEffect hook
Client Code
// Keeps track of whether message was successfully sent
const [isMessageSent, setIsMessageSent] = useState({
status: "failure",
render: false
});
useEffect(() => {
// Connecting to our endpoint and creating an event
socket = io(ENDPOINT, connectionOptions);
// If message has been successfully sent...
if (isMessageSent.status === "success") {
socket.emit("messageToServer", isMessageSent);
}
// Now that the server has acknowledged message has beent sent
// we will set it back to false and reredner everything
socket.on("messageFromServer", ({ status, render }) => {
// Triggering a re-render since message was successful
setIsMessageSent({ ...isMessageSent, status, render });
// Setting it back to default in the event of a new message
setIsMessageSent({ ...isMessageSent, status: "failure", render: false });
});
}, [history, ENDPOINT, isMessageSent]);
Server Code
// Socket.io related code
io.on("connection", (socket) => {
socket.on("messageToServer", (isMessageSent) => {
// That means message was successfully sent, set it back to false
if (isMessageSent.status === "success") {
io.emit("messageFromServer", { ...isMessageSent, render: true });
}
});
});