Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

369
Visualizações
Socket.io y React: ¿La forma correcta también de recibir datos del servidor y establecer el estado en un componente?

Tratando de poner en marcha una aplicación de chat básica y teniendo problemas con repeticiones excesivas cuando se envía un mensaje. Aquí está el código aplicable para el cliente:

 const [chatMessages, setChatMessages] = useState([]); const sendChat = (e) => { socket.emit("sendMessage", e.target.elements.message.value); } useEffect(() => { socket.on("receiveMessage", (chatMessage) => { setChatMessages([...chatMessages, chatMessage]); console.log(chatMessages); }); }, [chatMessages]); return ( {chatMessages.map((message) => <p>{message}</p>)} )

Luego, en el servidor:

 io.on("connection", (socket) => { socket.on("sendMessage", (chatMessage) => { console.log("message sent"); io.to(roomId).emit("receiveMessage", chatMessage); }); }

Cuando hago esto, el mensaje se envía y recibe con éxito, pero sucede muchas veces (consola):

 [] [] [{...}] [{...}] (2) [{...}, {...}]

En el tercer mensaje esto es lo que se registra. En el sexto o séptimo mensaje, toda la página se detiene bruscamente, ya que se registra unas 100 veces.

He probado lo siguiente:

  1. Tener una matriz de dependencias vacía en useEffect() . Esto soluciona los renderizados, pero presenta un nuevo problema. El último mensaje es el único que se guarda y reemplaza al último, por lo que solo puede ver un mensaje a la vez.

  2. Sacándolo de useEffect() todos juntos. Esto solo empeora el problema y provoca aún más repeticiones por mensaje.

Cualquier ayuda sería apreciada. ¡Gracias!

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Tema

Está creando controladores de eventos de socket cuando el estado de chatMessages se actualiza pero no los limpia . Si edita su código o el componente se vuelve a renderizar, etc... entonces se agrega otro controlador de eventos de socket. Los múltiples controladores comenzarán a acumularse y a poner en cola múltiples actualizaciones de estado inesperadas.

Además, dado que las actualizaciones de estado de React se procesan de forma asíncrona, no puede registrar el estado inmediatamente después de poner en cola la actualización y esperar ver el estado actualizado. Use un useEffect separado para esto.

Solución

  1. Agregue una función de limpieza useEffect para eliminar el controlador de eventos y vuelva a incluir la matriz de estado de chatMessages actualizada en la devolución de llamada del controlador.

     useEffect(() => { const handler = (chatMessage) => { setChatMessages([...chatMessages, chatMessage]); } socket.on("receiveMessage", handler); return () => socket.off("receiveMessage", handler); }, [chatMessages]);
  2. Agregue una función de limpieza useEffect , elimine las dependencias para que el efecto se ejecute una vez en el montaje del componente y use una actualización de estado funcional para actualizar correctamente desde el estado anterior en lugar del estado inicial en el gabinete de devolución de llamada.

     useEffect(() => { const handler = (chatMessage) => { setChatMessages(chatMessages => [...chatMessages, chatMessage]); } socket.on("receiveMessage", handler); return () => socket.off("receiveMessage", handler); }, []);

Entre las dos la segunda opción es la solución más óptima, pero la que elijas es tu decisión.

Para registrar las actualizaciones de estado de chatMessages :

 useEffect(() => { console.log(chatMessages); }, [chatMessages]);
about 4 years ago · Juan Pablo Isaza Relatório

0

Dado que tiene una dependencia de chatMessages , cada vez que cambia chatMessages , crea un nuevo oyente. Y es por eso que se vuelve más y más lento a medida que ingresan más mensajes.

Podrías hacer dos cosas:

  1. Mantienes los chatMessages de chat localmente dentro del método useEffect . Y puede difundir esa matriz y simplemente llamar a setChatMessages con la matriz extendida. Cuando haga esto, puede eliminar la dependencia de chatMessages para useEffect y aún tener todos los mensajes. Como buena práctica, debe devolver una función que elimine el detector de eventos cuando se desmonte el componente.

 const [chatMessages, setChatMessages] = useState([]); const sendChat = (e) => { socket.emit("sendMessage", e.target.elements.message.value); } useEffect(() => { let localMessages = []; const callback = (chatMessage) => { localMessages = [...localMessages, chatMessage]; setChatMessages(localMessages); console.log(localMessages); }; socket.on("receiveMessage", callback); return () => { socket.off("receiveMessage", callback); } }, []); return ( {chatMessages.map((message) => <p>{message}</p>)} )

  1. Probablemente pueda usar useRef para almacenar los valores. Sin embargo, eso no activará la nueva representación de la interfaz de usuario cuando cambie el valor y probablemente eso no sea lo que desea. Así que esta puede no ser una buena opción.
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda