[英]Chat App Using React and Socket.io Hanging After Sending Too Many Messages
我的基本聊天应用程序在发送大约 7 条消息后变得非常慢,尽管它在只发送几条消息时确实有效。
我在返回的组件中放置了一个打印语句。 我注意到每次提交聊天消息时,打印语句的调用次数是以前的两倍。 我认为我的应用程序变得越来越慢,因为当我发送更多消息时,不得不以指数方式重新渲染 DOM。
有没有人对为什么会发生这种情况有任何想法?
这是我的 React 应用程序
import React from 'react';
import io from "socket.io-client";
let socket = io.connect("localhost:8080");
function App() {
const [curMessage, setMessage] = React.useState({name: "", message: ""});
const [messageList, setList] = React.useState([]);
socket.on("receiveMsg", message => {
setList([...messageList, message]);
});
function handleTyping(e) {
let target = e.target;
if (target.id === "name") {
setMessage({...curMessage, name: target.value});
} else {
setMessage({...curMessage, message: target.value});
}
}
function handleSubmit(e) {
e.preventDefault();
setList([...messageList, curMessage]);
setMessage({name: "", message: ""});
socket.emit("message", curMessage);
}
return (
<div>
<form onSubmit={handleSubmit}>
<input id="name" onChange={handleTyping} value={curMessage.name}></input>
<input id="message" onChange={handleTyping} value={curMessage.message}></input>
<button>Send Message</button>
</form>
<ul>
{messageList.map(msg => {
return <li> {msg.name} {msg.message} </li>
})}
{console.log("test")}
</ul>
</div>
);
}
export default App;
这是我的服务器端代码(虽然我认为这段代码很好)
const express = require("express");
const app = express();
const http = require("http").createServer(app);
const io = require("socket.io")(http);
http.listen(8080, () => console.log("Connected to Server"));
io.on("connection", socket => {
console.log("User has connected " + socket.id);
socket.on("message", data => {
socket.broadcast.emit("receiveMsg", data);
});
});
尝试将socket.on(..)
放在 useEffect 中。 也许在渲染中执行 setState 是速度变慢的原因。
useEffect(() => {
socket.on("receiveMsg", (message) => {
setList([...messageList, message]);
});
return () => {
socket.off("receiveMsg");
};
}, [messageList]);
Chanandrei 给出的答案有一个小陷阱。 让我解释一下。
而这种模式还在继续..
useEffect(() => { socket.on("receiveMsg", (message) => { setList([...messageList, message]); }); return () => { socket.off("receiveMsg"); }; }, [messageList]);
问题是您不想在每次更新 messageList 时都创建一个新的 socket.io 侦听器。 在组件的生命周期内,您应该始终只为一个事件创建一个侦听器。 因为一旦 socket.on 侦听器被创建,它就不会在侦听该事件的第一次发生后被销毁,它只是再次侦听该事件。
所以这样的监听器必须创建一次。 在您的情况下,它应该在组件安装时创建。
因此使用[]
,空列表作为 useEffect 的第二个参数。 这个钩子相当于 componentDidMount。
useEffect(() => { socket.on("receiveMsg", (message) => { setList([...messageList, message]); }); return () => { socket.off("receiveMsg"); }; }, []);
使用此代码,您将收到一条警告,提示您需要将messageList作为 useEffect 中的依赖项
useEffect(() => {
socket.on("receiveMsg", (message) => {
setList([...messageList, message]);
});
return () => {
socket.off("receiveMsg");
};
}, []);
你只需要像这样进行功能更新
setList((prevMsgs) => [...prevMsgs, message]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.