React 구성 요소에서 소켓 이벤트 리스너가 여러 번 실행됩니다.

4808 단어 socketjavascriptreact
기본적이지만 종종 간과되는 사이드 프로젝트를 하면서 배운 것이 있습니다.

일부 컨텍스트



이 프로젝트에는 단순히 두 가지 주요 부분이 포함되어 있습니다.
  • 프런트 엔드: 반응 및 재료 UI
  • 백엔드: Express, Typescript, Firebase 및 Socket.io를 사용하는 REST API

  • 내 목표는 Socket.io를 사용하여 데이터가 업데이트될 때 프런트 엔드에 알리고 데이터를 다시 가져오도록 하는 것이었습니다.



    잘못된 시도



    소켓 이벤트를 수신하고 데이터를 다시 가져오는 잘못된 코드 스니펫이 있었습니다.

    내 첫 번째 시도는 재렌더링이 있을 때마다 socket.on('USER_JOINED')가 전달된 동일한 callback 함수를 등록하여 이벤트USER_JOINED가 발생하면 동일한 콜백이 여러 번 실행되는 것입니다. API 호출과 성능을 분명히 줄이기 위해 한 번 실행하십시오.

    const Expense = () => {
      const [initialValues, setInitialValues] = useState(null);
      const [expense, setExpense] = useState(null);
      const { socket, toLogIn } = useContext(SWContext);
      // ...
      socket.on('USER_JOINED', (socketData) => {
        // fetch data again
      });
    }
    
    


    두 번째 시도는 구성 요소가 마운트될 때 콜백을 한 번 등록하는 것이었지만 여전히 여러 콜백 실행을 경험했습니다. 구성 요소가 마운트 해제된 후에도 콜백이 여전히 socket에 등록되어 있기 때문입니다(저는 소켓의 단일 인스턴스(싱글톤 패턴)를 사용합니다). 상태가 업데이트되면 새 상태에 액세스할 수 없습니다.

      useEffect(() => {
        socket.once('USER_JOINED', (socketData) => {
          // fetch data again
        });
      }, []);
    


    해결책



    이것은 지금까지 나를 위해 작동합니다. socket.off가 변경될 때마다 소켓 이벤트 핸들러와 정리expense를 등록합니다. 이렇게 하면 한 번에 하나의 소켓 이벤트 핸들러만 호출되고 필요하지 않을 때 분리됩니다.

      useEffect(() => {
        socket.once('USER_JOINED', (socketData) => {
          // fetch data again
        });
        return socket.off('USER_JOINED');
      }, [expense]);
    


    이 방법은 window.addeventlistener()와 같은 유사한 상황에도 적용될 수 있다고 생각합니다.


    궁금하시면 제 프로젝트를 살펴보세요https://github.com/TueeNguyen/SplitWise3

    좋은 웹페이지 즐겨찾기