简体   繁体   English

如何在反应中使用 socket.on?

[英]How to use socket.on in react?

I am building a small chat app, but I have problems with receiving messages in react.我正在构建一个小型聊天应用程序,但在接收消息时遇到问题。 The problem is that when I receive a message I setMessages , but at the same time the messages state gets cleared.问题是,当我收到一条消息时,我setMessages ,但同时messages状态被清除。 The problem is problably that I don't know where to place socket.on , currently it's inside a useEffect hook.问题可能是我不知道在哪里放置socket.on ,目前它在useEffect钩子内。

export const Room = ({ socket }) => {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState("");
  const { id } = useParams();
  
  useEffect(() => {
    socket.emit("join room", id);
  }, []);

  useEffect(() => {
    socket.on("message", (message) => {
      setMessages([
        ...messages,
        { message: message, createdBy: "other", id: uuidv4() },
      ]);
    });
  }, []);
  const sendMessage = () => {
    console.log("send");
    socket.emit("message", input);
    setMessages([
      ...messages,
      { message: input, createdBy: "me", id: uuidv4() },
    ]);
  };
  console.log("foo");
  return (
    <div className="flex justify-center text-center">
      <div className="w-screen h-screen px-2 max-w-4xl mt-10">
        <p className="text-3xl">Code: {id}</p>
        <div className="bg-white w-full h-3/4 rounded-xl border-2 border-black overflow-y-auto">
          {messages.map((message) => (
            <Message
              text={message.message}
              createdBy={message.createdBy}
              key={message.id}
            />
          ))}
        </div>
        <div className="flex flex-row border-2 border-black mt-2 rounded-xl p-2 bg-white">
          <input
            className="flex-grow border-none focus:outline-none"
            onInput={(e) => setInput(e.target.value)}
          />
          <button
            className=" bg-green-500 rounded-xl px-2 py-1"
            onClick={sendMessage}
          >
            Send
          </button>
        </div>
      </div>
    </div>
  );
};

I'm pretty sure you have a closure problem.我很确定你有关闭问题。 messages is not what you think it is when it is run inside the useEffect -- it may not be the latest version. messages在 useEffect 中运行时不是您认为的那样 - 它可能不是最新版本。

It's safer and good practice to use the functional variant of the setter.使用 setter 的函数变体是更安全和良好的做法。 This way you can be certain that messages is the current version:这样您就可以确定messages是当前版本:

setMessages(messages => [
  ...messages,
  { message: message, createdBy: "other", id: uuidv4() },
]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM