繁体   English   中英

开发工具显示了许多 websocket 聊天应用程序的请求,这些请求是由带有功能组件的反应钩子构建的

[英]Dev tools show many websocket requests of chat app built by react hook with functional component

我使用 websocket、react hook、react 功能组件和 typescript 创建了一个 web 聊天客户端。

我的问题是它在一个客户端之后生成一个新的 websocket 请求,该请求是由带有钩子的反应功能组件构建的,向另一个客户端发送或接收消息,这与由带有功能组件的反应钩子构建的相同。 我从网络选项卡中观察到这种情况,并在浏览器开发工具中过滤 websocket。 我希望聊天期间只有一个 websocket 连接。

但是当我使用 react class 组件类型实现另一个客户端版本时,这种版本在整个发送和接收消息期间仅显示一个 websocket。

您可以从我的 github 存储库中读取App.tsx代码。 以下是 React-hook 类型客户端的App.tsx摘录:

export const App: React.FC<{}> = ({}) => {

  const [messages, setMessages] = useState<MessageType[]>([]);
  const testValue = { messages, setMessages };

  const ws = useRef(new WebSocket(URL));

  const renderCount = useRef(0);

  const submitMessage = (msg: MessageType) => {
    ws.current.send(JSON.stringify(msg));

    addMessage(msg);
  };

  const addMessage = (msg: MessageType) => {

    setMessages([...messages, msg]);

  };

  // websocket onmessage
  useEffect(() => {
    ws.current.onmessage = (msg) => {
      const message = JSON.parse(msg.data);
      message.isMe = false;

      addMessage(message);
    };

    console.log(`hello`);
  });

  // close websocket
  useEffect(() => {
    return () => {
      ws.current.close();
    };
  }, [ws]);


  return (
    <StylesProvider injectFirst>
      <div className="App" css={appStyle}>
        <AppBar position="sticky">
          {console.log(`renderCount: ${(renderCount.current += 1)}`)}
          {/* debug */}
          <Toolbar>
            <IconButton edge="start" color="inherit" aria-label="menu">
              <MenuIcon />
            </IconButton>
            <Typography variant="h6">聊天室</Typography>
          </Toolbar>
        </AppBar>

        <MessageHistory messages={messages} />
        <ChatInput submitFC={submitMessage} />
      </div>
    </StylesProvider>
  );
};

下面是两个本地客户端的截图:
接收者:
在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

发件人:
在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

react class 组件构建的其他客户端版本的存储库位于我的 github 存储库中。

聊天服务器的仓库在我的 github 另一个仓库

我根据stackoverflow上其他问题的解决方案解决了这个问题,但我不知道为什么。 带钩子的 react 功能组件版本现在在整个聊天过程中只能使用一个 websocket。

下面标记为“// 在此处更改”的代码是App.tsx的解决方案:

export const App: React.FC<{}> = ({}) => {

  const [messages, setMessages] = useState<MessageType[]>([]);
  const testValue = { messages, setMessages };

  // const ws = useRef(new WebSocket(URL));
  const ws = useRef<WebSocket | null>(null);  // changed here

  const renderCount = useRef(0);

  const submitMessage = (msg: MessageType) => {
    if (ws.current) {   // changed here
      ws.current.send(JSON.stringify(msg));
    }  // changed here

    addMessage(msg);
  };

  const addMessage = (msg: MessageType) => {

    setMessages((prev) => {   // changed here
      return [...prev, msg];  // changed here
    });                       // changed here
  };

  // websocket onmessage
  useEffect(() => {
    ws.current = new WebSocket(URL);  // changed here
    ws.current.onmessage = (msg: MessageEvent) => { // changed here
      const message = JSON.parse(msg.data);
      message.isMe = false;

      addMessage(message);
    };
  }, []);                     // changed here

  // close websocket
  useEffect(() => {
    return () => {
      if (ws.current) {       // changed here
        ws.current.close();
      }                       // changed here
    };
  }, [ws]);



  return (
    <StylesProvider injectFirst>
      <div className="App" css={appStyle}>
        <AppBar position="sticky">
          {console.log(`renderCount: ${(renderCount.current += 1)}`)}
          {/* debug */}
          <Toolbar>
            <IconButton edge="start" color="inherit" aria-label="menu">
              <MenuIcon />
            </IconButton>
            <Typography variant="h6">聊天室</Typography>
          </Toolbar>
        </AppBar>

        <MessageHistory messages={messages} />
        <ChatInput submitFC={submitMessage} />
      </div>
    </StylesProvider>
  );
};

下面是截图。 在此处输入图像描述 在此处输入图像描述

暂无
暂无

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

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