Attempting to create a simple React chat app, but I'm running into an issue where duplicate messages appear. I run the server with node server.js, in a separate terminal run the client with npm start, then open two windows at localhost:3000. I can send a message, but any message I send is received x2. For example (after submitting the form with "i only sent this once" on one window, this is what appears in the second window).:

I did console.log on the server-side, and only one message is being received from the server.
Here is my server.js file:
const express = require("express");
const socketio = require("socket.io");
const http = require("http");
const cors = require("cors");
const PORT = process.env.PORT || 5001;
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(cors());
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
io.on("connection", (socket) => {
socket.on("connection", () => {});
socket.on("send-message", (message) => {
console.log(message);
socket.broadcast.emit("message", message);
});
});
Here's my socket.js file:
import io from "socket.io-client";
const SERVER = "http://127.0.0.1:5001";
const connectionOptions = {
forceNew: true,
reconnectionAttempts: "Infinity",
timeout: 10000,
transports: ["websocket"],
};
let socket = io.connect(SERVER, connectionOptions);
export default socket;
Here's my App.js file:
import { useState, useEffect } from "react";
import "./App.css";
import socket from "./socket";
const ChatWindow = () => {
const [message, setMessage] = useState("");
const [messages, setMessages] = useState([]);
const handleMessageChange = (event) => {
setMessage(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
socket.emit("send-message", { message: message });
};
useEffect(() => {
socket.on("connection", null);
socket.on("message", (payload) => {
setMessages((prev) => {
return [...prev, payload.message];
});
});
}, []);
return (
<div>
{messages.map((message) => {
return <h3>message: {message}</h3>;
})}
<form onSubmit={handleSubmit}>
<input value={message} onChange={handleMessageChange}></input>
<button type="submit">Send Message</button>
</form>
<h1>Chat Window</h1>
</div>
);
};
function App() {
return (
<div className="App">
<ChatWindow />
</div>
);
}
export default App;
If you are using UseEffects Hooks you need to clean up
Before :
useEffect(() => {
socket.on("connection", null);
socket.on("message", (payload) => {
setMessages((prev) => {
return [...prev, payload.message];
});
});
}, []);
You can add this line to clean up :
useEffect(() => {
socket.on("connection", null);
socket.on("message", (payload) => {
setMessages((prev) => {
return [...prev, payload.message];
});
});
return () => socket.off("message"); // add this line to your code
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With