Reputation: 33
Server part:
const express = require("express");
const app = express();
const cors = require("cors");
const { UserModel } = require("./models");
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.options("http://localhost:3000", cors());
const mongoose = require("mongoose");
require("dotenv").config();
const http = require("http").createServer(app);
const io = require("socket.io")(http, {
cors: {
origin: ["http://localhost:3002"],
},
});
http.listen(3001, function () {
console.log("Server is running");
});
io.on("connection", (socket) => {
console.log("Socket connected", socket.id);
socket.on("message:send", (data) => {
console.log("Пришло в socket.onMessage", data);
socket.emit("message:fromServer", data);
// socket.removeListener("message:fromServer");
});
});
const { userApi } = require("./api/userApi");
app.use("/", userApi);
app.use((err, _, res, __) => {
return res.status(500).json({
status: "fail",
code: 500,
message: err.message,
});
});
const { PORT, DB_HOST } = process.env;
const dbConnection = mongoose.connect(DB_HOST, {
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
useUnifiedTopology: true,
});
dbConnection
.then(() => {
console.log("DB connect");
app.listen(PORT || 3000, () => {
console.log("server running");
});
})
.catch((err) => {
console.log(err);
});
Client part: io.js
import { io } from "socket.io-client";
export const socket = io("http://localhost:3001/");
Message component
import React from "react";
import { useState } from "react";
// import { useSelector } from "react-redux";
// import { getMessages } from "../../Redux/selectors";
import { socket } from "../helpers/io";
import Message from "../Message/Message";
import { nanoid } from "nanoid";
export default function MessageFlow() {
const [message, setMessage] = useState([]);
socket.on("message:fromServer", (data) => {
console.log("На фронт пришло сообщение: ", data);
setMessage([...message, data]);
// setMessage((message) => [...message, data]);
console.log("Массив сообщений компонента MessageFlow", message);
console.log(socket.io.engine.transports);
// socket.off();
// getEventListeners(socket)['testComplete'][0].remove()
// socket.removeListener("message:fromServer");
});
// const dispatch = useDispatch();
// const allMessages = useSelector(getMessages);
return (
<div id="mainDiv">
{message &&
message.map((i) => {
// return <Message />;
return <Message content={i.userId} id={nanoid()} />;
})}
</div>
);
}
Message Form - the beginning of emitting process
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { sendMessage } from "../../Redux/Chat/Chat-operations";
import { getUser } from "../../Redux/selectors";
import { getToken } from "../../Redux/Auth/Auth-selectors";
import { socket } from "../helpers/io";
import { useEffect } from "react";
import styles from "./MessageForm.module.css";
export default function MessageForm() {
const [message, setMessage] = useState("");
const dispatch = useDispatch();
const userId = useSelector(getUser);
const currentToken = useSelector(getToken);
// const getAll = useSelector(allContacts);
const updateMessage = (evt) => {
setMessage(evt.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (message) {
socket.emit("message:send", { userId: message });
dispatch(
sendMessage(
{
_id: userId,
text: message,
},
currentToken
)
);
} else {
alert(`Молчать будем?`);
}
};
return (
<div className={styles.messageInputContainer}>
<form>
<input
type="text"
value={message}
onChange={updateMessage}
required
className={styles.messageInput}
placeholder="Type message to send"
/>
<button
type="submit"
className={styles.messageAddBtn}
onClick={handleSubmit}
>
Send
</button>
</form>
</div>
);
}
Upvotes: 2
Views: 1165
Reputation: 578
You add a listener on every render, you should use useEffect hook
export default function MessageFlow() {
useEffect(()=>{ // triggered on component mount or when dependency array change
const callback = (data) => {
// what you want to do
}
socket.on("message:fromServer", callback);
return () => { // on unmount, clean your listeners
socket.removeListener('message:fromServer', callback);
}
}, []) // dependency array : list variables used in your listener
// [...]
}
Upvotes: 2