簡體   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