状态值不正确?

时间:2020-01-01 15:10:55

标签: reactjs sockets socket.io

下面的代码是一个聊天客户端(使用socket.io)。用户发送消息后(事件“ usr_input”),服务器将以“消息”事件进行响应。收到消息(console.log(msg)),创建数组的副本([... chatMessages]),并更新消息数组。但是,当再次调用该函数时,该值不正确(我看到聊天消息的副本附加了新消息,但类状态为空数组)。但是状态已更新(已通过useEffect验证)。

import React, { useState, useCallback, useEffect } from "react";
import "./styles/chat.css";
import { uuidv4 } from "./utils/utils";
const SERVER_URL = "http://localhost:3337";
const io = require("socket.io-client");


function ChatManager(props) {
  // How to handle sockets (where do we store them)
  const [UId, setUId] = useState("");
  const [socket, setSocket] = useState(null);
  const [chatMessages, setChatMessages] = useState([]);
  const [role, setRole] = useState("Role");
  const useForceUpdate = () => useState()[1];
  function displayMessage(msg) {
    if (UId) {
      if (msg.user === UId) {
        return (
          <article class="msg-container msg-self" id="msg-0">
            <div class="msg-box">
              <div class="flr">
                <div class="messages">
                  <p class="msg" id="msg-0">
                    {msg.message}
                  </p>
                </div>
              </div>
            </div>
          </article>
        );
      } else {
        return (
          <article class="msg-container msg-remote" id="msg-0">
            <div class="msg-box">
              <div class="flr">
                <div class="messages">
                  <p class="msg" id="msg-0">
                    {msg.message}
                  </p>
                </div>
              </div>
            </div>
          </article>
        );
      }
    }
  }

  function addMessage(msg) {
    console.log("message: ");
    console.log(msg);
    const newMessages = [...chatMessages];
    console.log(chatMessages);
    newMessages.push(msg);
    console.log(newMessages);
    setChatMessages(newMessages);
    console.log("Message added");

  }

  useEffect(() => {
    console.log("did mount");
    if (!socket) {
      setUId(uuidv4());
      console.log("Set UId");
      setSocket(io.connect(SERVER_URL));
      console.log("Socket mounted");
    } else {
      console.log("Socket emit");

      socket.emit("join", {
        uid: UId,
        tid: "Task ID, add later",
        role: role
      });

      socket.on("error", function(err) {
        console.log("received socket error:");
        console.log(err);
      });

      socket.on("message", function(msg) {
     addMessage(msg);
      });
    }
    return () => {
      console.log("Unmounting");
      if (socket) {
        socket.emit("leave", {
          uid: UId,
          tid: "Task ID, add later",
          role: role
        });
        console.log("Leaving message sent");
      }
    };
  }, [socket]);

  function sendMessage() {
    const msg = "Test message";
    socket.emit("usr_input", {
      uid: UId,
      tid: "Task ID, add later",
      message: msg,
      role: role
    });

    console.log("Message sent");
  }

return (
    <div>
      <h1> Here is the chatbox </h1>
      <ChatBox 
      sendMessage={sendMessage} 
      chatMessages={chatMessages}
      displayMessage={displayMessage}/>
      <h1> EOF </h1>
    </div>
  );
}

function ChatBox(props) {
  return (
    <section class="chatbox">
      <section id="chat-messages" class="chat-window">
        {props.chatMessages.map( (msg) => {props.displayMessage(msg)})}
      </section>

    <form class="chat-input" onsubmit="return false;">
        <input
          type="text"
          id="message"
          autocomplete="on"
          placeholder="Type a message"
        />
        <button type="button" onClick={props.sendMessage}>
          <svg
            style={{
              width: "24px",
              height: "24px"
            }}
            viewBox="0 0 24 24"
          >
            {" "}
            <path
              fill="rgba(0,0,0,.38)"
              d="M17,12L12,17V14H8V10H12V7L17,12M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L5,8.09V15.91L12,19.85L19,15.91V8.09L12,4.15Z"
            />{" "}
          </svg>{" "}
        </button>
      </form>
    </section>
  );
}

我尝试通过调用useState强制进行更新,但是收到此错误(https://dev.to/ranewallin/js-bites-react-hook-is-called-in-a-function-which-is-neither-a-react-function-or-sic-a-custom-react-hook-1g2c)。

任何要测试的建议或想法将不胜感激!

编辑:根据新信息更改标题和文本。

0 个答案:

没有答案
相关问题