Javascript 在使用套接字io后,要在react中进行更多的重新渲染

Javascript 在使用套接字io后,要在react中进行更多的重新渲染,javascript,reactjs,socket.io,Javascript,Reactjs,Socket.io,我正在做一些类似于omegle的事情,这是我的一些代码,看看useEffect函数 const Messanger =(props)=>{ let socket = props.socket; let intro; const myId = socket.id; const [readOnly,setReadOnly] = useState(true); const [messages,setMessages]=useState([]); const [stranger_name,setS

我正在做一些类似于omegle的事情,这是我的一些代码,看看useEffect函数

const Messanger =(props)=>{
let socket = props.socket;
let intro;
const myId = socket.id;
const [readOnly,setReadOnly] = useState(true);
const [messages,setMessages]=useState([]);
const [stranger_name,setStranger_name] = useState(null);
const [disconnected,setDisconnected] = useState(false);
const [room,setRoom] = useState(null);
let messageRef = React.createRef();
let messagesEnd =React.createRef();



当服务器在两个用户之间找到匹配项时,它将他们连接到一个房间中,然后向两个用户发送joinRoom套接字请求,通知前台他们已连接



useEffect(()=>{

  socket.once("joinRoom",(data)=>{
    setDisconnected(false);

  setMessages([]);
  setStranger_name(data.name);
  setRoom(data.room);
   setReadOnly(false);
  console.log("JOING ROOM")
});


},[stranger_name])
当用户接收到消息时,将触发此脚本

useEffect(()=>{
  socket.once('messageToClient',(data)=>{
    setMessages([...messages,{message:data.message,id:data.id}])         
    });
    scrollToBottom();
},[messages])



在这里,在渲染之前,我会记录一些文本,以查看渲染的次数

console.log('render')

return (DOM)

主要问题是,每次我与正在聊天的用户断开连接并重新开始时,DOM会多次重新呈现,例如,当收到消息时,console.log代码会触发4次,当我开始与另一个用户聊天时,console.log'render'函数被触发8次,以此类推,当消息更改时,通过重新订阅套接字事件,导致setMessages被多次触发,从而导致钩子重新订阅等,实际上是在创建一个无限循环

以下是一个临时文件。修复但不是完整的答案,因为您应该在组件外部处理套接字消息,将它们存储在redux中,然后使用它们

useEffect(()=>{
  socket.once('messageToClient',(data)=>{
    setMessages((prevMessages)=>[...prevMessages,{message:data.message,id:data.id}])         
    });
    scrollToBottom();
},[])

听起来是时候坐下来花点时间来形成一个真正的世界了。这对我们来说不算什么,但对于您深入了解您的代码正在做什么,非常感谢。事实上,我第一次从数组中删除消息是为了避免你所说的循环,但是在那之后,setMessage函数没有正常工作,它只将消息设置为一条消息,prevMessages总是空的,但现在我更改setMessages的方式与你所做的相同,并且它工作正常,你能告诉我不同的setMessagesprevMessages=>[…prevMessages,{message:data.message,id:data.id}]和这个setMessages[…prevMessages,{message:data.message,id:data.id}]吗?还有,我的DOM在每个setState上重新呈现是正常的吗?例如,我有一个包含4个setStates的函数``const heDisconnecting==>{setDisconnectedtrue;setInchat!inchat;setRoomnull;setReadOnlytrue;}```为什么dom会在这些setStates函数上重新呈现?这正常吗?为什么不在父函数完成后重新渲染一次?@MohamadAlasly很高兴我能帮上忙!1.问题不同之处在于,您在更新previousState时获得了它的状态,因此不需要将其传入-如果您这样做,并且在useEffect中将其作为依赖项置于外部,则它会重新触发回调,因为依赖项发生更改,这可能会导致多次重新引用2。问题是的,这是正常的,hooks/setState是如何工作的。如果同时更新多个内容,也可以只使用一个useState{inChat:…,messeges:…,disconnected:…},这只会导致一次渲染