简体   繁体   中英

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.

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. I observe this situation from network tab with filtering websocket at browser dev tools. What I wish is there is only one websocket connection during chat.

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.

You can read the App.tsx code frommy github repository . Below are exerpt of App.tsx for react-hook type's client:

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 .

Chat server's repository is at my github another repository

I solve this problem based on this solution from other question at stackoverflow, but I don't know why. Version of react functional component with hook now can use only one websocket during a whole chat.

Below marked "// changed here" code are solution for 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. 在此处输入图像描述 在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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