React에서 다중 소켓 연결 및 이벤트를 방지하는 방법

11553 단어 socketioreactsocketspa
다중 소켓 연결 및 이벤트 바인딩은 SPA에서 쉽게 간과될 수 있으며 두통을 유발할 수 있습니다. 이를 예방한 제 경험을 공유하고 싶습니다. 이 기사에서는 Node.js 백엔드에 socket.io를 사용하고 React 프론트엔드에 socket.io-client를 사용합니다.

1. 한 번만 연결



소켓 연결을 위한 전용 파일을 생성합니다. 예를 들어 service/socket.js에 파일을 만듭니다.


import io from "socket.io-client";
import { SOCKET_URL } from "config";

export const socket = io(SOCKET_URL);

필요할 때마다 다른 React 구성 요소에서 이 소켓 인스턴스를 가져올 수 있습니다.

import {socket} from "service/socket";

function MyComponent() => {
   return(<div></div>)
}

이러한 방식으로 소켓 인스턴스가 하나만 있는지 확인할 수 있습니다.

2. 이벤트를 한 번만 바인드 및 방출 - 올바른 위치에 배치



페이지가 로드될 때 소켓 서버에 연결하고 연결에 성공하면 환영 메시지를 표시하는 React 구성 요소를 구축한다고 가정합니다. 구성 요소는 서버에 HELLO_THERE 이벤트를 내보내고 서버는 웜WELCOME_FROM_SERVER 이벤트로 응답합니다. React 코드에서 소켓 이벤트 바인딩 및 방출을 어디에 두시겠습니까?

import {socket} from "service/socket";
// NOT HERE (1)
// socket.emit('HELLO_THERE');
function MyComponent() => {

   // NOT HERE EITHER (2)
   // socket.emit('HELLO_THERE');
   const [connected, setConnected] = useState(false);
   // IT IS HERE
   useEffect(() => {
      socket.emit('HELLO_THERE');
      const eventHandler = () => setConnected(true);
      socket.on('WELCOME_FROM_SERVER', eventHandler);
      // unsubscribe from event for preventing memory leaks
      return () => {
         socket.off('WELCOME_FROM_SERVER', eventHandler);
      };
   }, []);
   return (
      <div>
          { connected ? (
               <p>Welcome from server!</p>
          ) : (
               <p>Not connected yet...</p>
          ) }
      </div>
   )
}
export default MyComponent

  • (1) MyComponent를 사용하지 않아도 이벤트가 발생합니다.
  • (2) MyComponent가 업데이트될 때마다 이벤트가 발생합니다.

  • * React 클래스를 사용하는 경우 componentDidMount가 소켓을 사용하기에 적합한 위치입니다. useEffect(() => {}, [])componentDidMount와 거의 동일합니다.
    ** 물론 socket.emit는 코드에서 필요한 모든 위치로 이동할 수 있습니다. 그러나 socket.on는 대부분의 경우 componentDidMount에 있어야 합니다.

    3. 확실하지 않은 경우 항상 이 핵이 있습니다.



    여전히 구성 요소가 동일한 리스너를 여러 번 어리석게 바인딩하는 이유를 알 수 없거나 하나의 이벤트에 대해 하나의 리스너만 바인딩하도록 하려면 socket.off 를 사용할 수 있습니다.

    socket.off('MY_EVENT', doThisOnlyOnce).on('MY_EVENT', doThisOnlyOnce);
    

    업데이트 - useContext 접근법


    useContext 후크를 사용하려면 다음과 같이 할 수 있습니다.

    socket.js

    import React from "react";
    import io from "socket.io-client";
    import { SOCKET_URL } from "config";
    
    export const socket = io(SOCKET_URL);
    const SocketContext = React.createContext(socket);
    
    app.js는 다음과 같아야 합니다.

    import React from "react";
    import SocketContext, { socket } from "context/socket";
    
    const App = () => (
       <SocketContext.Provider value={socket}>
          <OtherComponents />
       </SocketContext.Provider>
    );
    

    그런 다음 구성 요소의 어느 곳에서나 다음과 같은 소켓을 얻을 수 있습니다.

    import React from "react";
    import SocketContext from "context/socket";
    
    const OtherComponent = () => {
      const socket = React.useContext(SocketContext);
      ...
    };
    

    자세한 내용은 여기에서 내 다른 게시물을 읽을 수 있습니다.


    좋은 웹페이지 즐겨찾기