简体   繁体   English

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

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

I have created a web chat client using websocket, react hook, react functional components and typescript.我使用 websocket、react hook、react 功能组件和 typescript 创建了一个 web 聊天客户端。

My questions is that it generates new one request of websocket after a client, which is built by react functional component with hook, sending or receiving a message to the other client, which is same built by react hook with functional component.我的问题是它在一个客户端之后生成一个新的 websocket 请求,该请求是由带有钩子的反应功能组件构建的,向另一个客户端发送或接收消息,这与由带有功能组件的反应钩子构建的相同。 I observe this situation from network tab with filtering websocket at browser dev tools.我从网络选项卡中观察到这种情况,并在浏览器开发工具中过滤 websocket。 What I wish is there is only one websocket connection during chat.我希望聊天期间只有一个 websocket 连接。

But when I implement another client version using react class component type, this kind version only show one websocket during whole sending and receiving messages.但是当我使用 react class 组件类型实现另一个客户端版本时,这种版本在整个发送和接收消息期间仅显示一个 websocket。

You can read the App.tsx code frommy github repository .您可以从我的 github 存储库中读取App.tsx代码。 Below are exerpt of App.tsx for react-hook type's client:以下是 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>
  );
};

Below are screenshots of two local clients:下面是两个本地客户端的截图:
Receiver:接收者:
在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

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

The repository of other client version built by react class component is at my github repository . react class 组件构建的其他客户端版本的存储库位于我的 github 存储库中。

Chat server's repository is at my github another repository聊天服务器的仓库在我的 github 另一个仓库

I solve this problem based on this solution from other question at stackoverflow, but I don't know why.我根据stackoverflow上其他问题的解决方案解决了这个问题,但我不知道为什么。 Version of react functional component with hook now can use only one websocket during a whole chat.带钩子的 react 功能组件版本现在在整个聊天过程中只能使用一个 websocket。

Below marked "// changed here" code are solution for App.tsx :下面标记为“// 在此处更改”的代码是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>
  );
};

Below are screenshots.下面是截图。 在此处输入图像描述 在此处输入图像描述

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

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