Socket.io 从 React 在之后表现得很奇怪 5 消息

我正在尝试使用基本的聊天应用程序 socket.io 和 react, 但跑进了一个奇怪的问题。 该应用程序按预期工作,第一个 5 消息,然后在此之后,第6条消息被加载太长,并且通常在聊天窗口中不会显示一些先前消息。 如果有人可以帮助,我会很高兴。
以下是我为后端提供的代码:


const express = require/'express'/;
const app = express//;
const http = require/'http'/.createServer/app/;
const io = require/'socket.io'//http/;

io.on/'connection', socket => {
socket.on/'message', /{ name, message }/ => {
io.emit/'message', { name, message }/;
console.log/message/;
console.log/name/;
}/;
}/;

http.listen/4000, function // {
console.log/'listening on port 4000'/;
}/;


这是我在我的代码 App.js:


import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';

const App = props => {
const socket = io.connect/'http://localhost:4000'/;
const [details, setDetails] = useState/{ name: '', message: '' }/;
const [chat, setChat] = useState/[]/;


useEffect/// => {
socket.on/'message', /{ name, message }/ => {
setChat/[...chat, { name, message }]/; //same as {name:name,message:message}
}/;
}/;

const onMessageSubmit = e => {
e.preventDefault//;
const { name, message } = details;
socket.emit/'message', { name, message }/;
setDetails/{ name, message: '' }/;
};

return /
<div>
<form onsubmit="{onMessageSubmit}">
<input =="" onchange="{e" type="text" value="{details.name}"/> setDetails/{ ...details, name: e.target.value }/}
/&gt;
<input =="" onchange="{e" type="text" value="{details.message}"/> setDetails/{ ...details, message: e.target.value }/}
/&gt;
<button>Send</button>
</form>
<ul>
{chat &amp;&amp;
chat.map//chat, index/ =&gt; /
<li key="{index}">
{chat.name}:{chat.message}
</li>
//}
</ul>
</div>
/;
};

export default App;
已邀请:

龙天

赞同来自:

这是因为每次更新状态时,都会执行回调。 useEffect, 主要是您订阅
message

一次又一次。

经过几次迭代,您有几个尝试更新相同条件的订阅。 并且由于异步性质
setState

你看到一个奇怪的行为。

您只需要订阅一次,可以通过将空依赖参数传递给它来完成此操作
useEffect

, 这将使它起作用
componentDidMount



useEffect/// => {
socket.on/'message', /{ name, message }/ => {
setChat/[...chat, { name, message }]/;
}/;
}, []/;


编辑 - 应对

异步

并考虑到之前的聊天,您需要
setState

通过回调


useEffect/// => {
socket.on/"message", /{ name, message }/ => {
setChat//prevChat/ => prevChat.concat/[{ name, message }]//;
}/;
}, []/;


你可能想要
cleanup

, 当您的组件未安装时。 请看看
https://reactjs.org/docs/hooks ... eanup
.

要回复问题请先登录注册