【问题标题】:useEffect runs twice once recieve message from socket.io一旦从 socket.io 接收到消息,useEffect 运行两次
【发布时间】:2022-10-09 00:40:07
【问题描述】:

我正在使用 react、express 和 socket.io 构建一个简单的聊天应用程序。

每次客户端向服务器发送消息时,服务器都会将消息广播回给每个用户。从后端服务器接收回消息时出现问题。

每次用户收到一条消息,useEffect 将运行两次而不是只运行一次。

useEffect(() => {
    socket.on("broadcast_msg", (data) => {
      setMsg((list) => [...list, data]);
    });
  }, [socket]);

PS。后端服务器只向前端发送一次。 感谢您的每一个回复:D

完整代码

import React from "react";
import { useEffect } from "react";
import { useState } from "react";

function Chat(props) {
  const { socket, username, room } = props;
  const [input, setInput] = useState("");
  const [msg, setMsg] = useState([]);

  // send msg to server
  const send_msg = (e) => {
    if (input !== "") {
      socket.emit("send_msg", {
        room: room,
        author: username,
        message: input,
      });
    }
  };

  // listen to boardcast msg
  useEffect(() => {
    socket.on("broadcast_msg", (data) => {
      setMsg((list) => [...list, data]);
    });
  }, [socket]);

  return (
    <div className="chat">
      <div className="chat-header"></div>
      <div className="chat-body">
        {msg.map((data) => {
          return (
            <>
              <h1>{data.author}</h1>
              <h1>{data.room}</h1>
              <h1>{data.message}</h1>
            </>
          );
        })}
      </div>
      <div className="chat-footer">
        <input
          type="text"
          placeholder="Enter the message..."
          onChange={(e) => {
            setInput(e.target.value);
          }}
        />
        <button onClick={send_msg}>Send</button>
      </div>
    </div>
  );
}

export default Chat;

【问题讨论】:

    标签: reactjs express socket.io


    【解决方案1】:
    useEffect(() => {
        const eventListener = (data) => {
            setMsg((list) => [...list, data]);
        };
        socket.on("broadcast_msg", eventListener);
    
        return () => socket.off("broadcast_msg", eventListener);
      }, [socket]);
    

    与听众一起做。 再次触发时运行 useEffect 并清理侦听器,这应该可以解决问题。 或者在安装时只运行一次。

     useEffect(() => {
        socket.on("broadcast_msg", (data) => {
          setMsg((list) => [...list, data]);
        });
      }, []);
    

    【讨论】:

    • 它工作正常。太感谢了 !
    • 我有一个类似的案例,对我来说只有第一个选项它只运行一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 2022-10-30
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多