首页 > 解决方案 > 套接字在其他组件中启动连接

问题描述

我有一个难以理解的问题。我有 2 个 React 组件SigninChat与套接字的连接应该只发生在第二个组件Chat中。

    const url = 'http://localhost:4000';
    const socket = openSocket(url);

    const Chat = () => {

      useEffect(() => {
        subscribeToChanges();
      }, []);

    const subscribeToChanges = () => {
    socket.on('getAllMessages', message => {
      const {userMessage, userId} = message;
      setState(prevState => ({
        ...state,
        messages: [...prevState.messages, {userMessage, userId}]
      }));
    });
  };
     return (
        <div>
        </div>
      );
    };

    export default Chat;

但是当我在浏览器中更新这两个组件时,我会在我的后端日志中看到它们在两者中都显示了与套接字的相同连接。但据我了解,这仅在我更新“聊天”时才会发生

也许这在某种程度上受到路线的影响,或者我对套接字的了解不够

    <Switch>
      <Route exact path="/">
        <SignIn/>
      </Route>
     <Route exact path="/chat">
       <Chat/>
     </Route>
   </Switch>

标签: reactjssocketssocket.io

解决方案


您必须在组件内部而不是在文件中创建套接字实例,否则实例将在您导入文件时创建,而不是在渲染时创建

此外,当您卸载组件时,您必须清理 ip 您的套接字实例

 const url = 'http://localhost:4000';
 const Chat = () => {
      const socket = useRef(null);
      useEffect(() => {

        socket.current = openSocket(url); // create socket here and pass it on
        subscribeToChanges();
        return () => {
             // close socket on unmount
             socket.current.close();
        }
      }, []);

  const subscribeToChanges = () => {
    socket.current.on('getAllMessages', message => {
      const {userMessage, userId} = message;
      setState(prevState => ({
        ...state,
        messages: [...prevState.messages, {userMessage, userId}]
      }));
    });
  };
     return (
        <div>
        </div>
      );
    };

    export default Chat;

推荐阅读