Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Comercial
    • Calculadora

0

219
Vistas
My useState in React/NEXTjs is not appending the result from a socket.io event from the server, just overwriting it

Frameworks used: Next.js, Socket.io, React

I am making a simple messaging app. I am basically just emitting a message someone types, sending that message to the server, which is then "broadcasted" back through an event called "receive-chat-message". The issue I'm having is when the response is handled on the front end with "receive-chat-message", the [messages] state is not appending a new message to display, it's just overwriting the state.

My goal is to send a message to the server; the server then sends the message back to the client. I then append the new message on the client, sent from the server, to the [messages] state on the client, and then render the state of [messages]. The problem is it's only overwriting the [messages] state, and not appending new messages to it.

Code that sends message to the server

const [message, setMessage] = useState("");

  const handleChange = (e) => {
    setMessage(e.target.value);
  };

  const submitMessage = async () => {
    // socket.io
    const socket = io();
    socket.emit("send-chat-message", message, user);
    setMessage("");
  };

Front-End Code

const [messages, setMessages] = useState([]);

  useEffect(() => {
    const socket = io();
    socket.on("receive-chat-message", handleSetMessage);

    return () => socket.disconnect();
  }, []);

  const handleSetMessage = (data) => {
    /* data prop is the new message - it has a {message: "message", user: "name"} 
       sent from server.
       THIS IS THE PROBLEM IN THE CODE WHERE IT DOESN'T APPEND
       NEW MESSAGES TO THE [messages] STATE, IT JUST OVERWRITES
       THE CURRENT STATE WITH THE NEW MESSAGE. */

    setMessages([...messages, data]);
  };

Back-End Code

export default async function handler(req, res) {
    if (!res.socket.server.io) {
      const io = new Server(res.socket.server);
      res.socket.server.io = io;

      io.on("connection", async (socket) => {
        socket.on("send-chat-message", async (message, user) => {
          socket.broadcast.emit("recieve-chat-message", 
          {
            message,
            name: user && user.name,
          });
        });
      });
   }
 }
7 months ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I solved this by setting messages through the functional method like:

setMessages((messages) => [...messages, data]);

Instead of:

setMessages([...messages, data])

I think we need this because I was updating the state from a function called within a socket.io listener and was never actually grabbing the previous state; so I had to direct it to the previous state and then merge the values.

7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos