I am working on a create-react-app project and am trying to incorporate a chat console powered by sockets.io. The problem is that while the chat message is being correctly captured by the front end, sent back to the io server, and then emitted, and the front end is successfully catching those messages, none of the information is passed between users, everything is only happening on the single browser instance. On the backend I have a console logging "new client connected" when someone connects. I noticed that that console is firing a couple of times each time a message is sent, making me think that the problem is somewhere in the react re-rendering process (so the rerenders are triggering a reconnect to the sockets server.)
The code:
Server:
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const PORT = process.env.PORT || 4001;
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server);
io.on("connection", socket => {
console.log("New client connected");
socket.on("chat message", function(msg) {
console.log("message: " + msg);
socket.emit("chat message", [msg]);
});
socket.on("disconnect", () => console.log("Client disconnected"));
});
server.listen(PORT, () => console.log(`Listening on port ${PORT}`));
app.js (root component)
import React, { useState, useEffect } from "react";
import "./App.css";
import Board from "./components/Board/Board";
import TileCard from "./components/TileCard/TileCard";
import Chat from "./components/Chat/Chat";
import Choice from "./components/Choice/Choice";
import Header from "./components/Header/Header";
import socketIOClient from "socket.io-client";
function App() {
const socket = socketIOClient("http://127.0.0.1:4001");
const [textValue, setTextValue] = useState("");
function handleChatSend(chatMsg) {
setTextValue(chatMsg);
socket.emit("chat message", chatMsg);
}
useEffect(() => {
socket.on("chat message", msg => {
setTextValue(msg);
console.log("receiving:" + msg);
});
}, [textValue]);
return (
<>
<Header />
<div className="content-container">
<Board />
<div className="cards-container col">
<Chat handleChatSend={handleChatSend} textValue={textValue} />
<TileCard />
<Choice />
</div>
</div>
</>
);
}
export default App;
the chat component:
import React from 'react';
import "./chat.css"
function Chat ({handleChatSend, textValue}) {
return (
<div className="chatbox">
<ul id="messages">
{textValue !== "" ? <li>{textValue}</li> : null}
</ul>
<form onSubmit={event =>{
event.preventDefault();
let chatMsg = event.target.elements[0].value;
handleChatSend(chatMsg)}}>
<input type="text" id="m" autoComplete="off" /><button type="submit">Send</button>
</form>
</div>
)
}
export default Chat;