useEffect 활용하여 react eventlistener 설정할 때 주의해야할 점

제이슨·2021년 10월 22일
2

useEffect 안에 eventlistener와 같은 subscribe형 함수를 더하고 제거하는 작업을 할 때

useEffect(() => {
  const subscription = props.source.subscribe();
  return () => {
    // Clean up the subscription
    subscription.unsubscribe();
  };
});

위와 같이 작업해야하는 것은 알고 있다. 그런데 왜 이렇게 해야할까? unsubscribe과 같은 clean up은 useEffect에서 componentWillUnmount의 역할을 하는 return 함수 자리에만 넣을 수 있는 걸까?

useEffect(() => {
  const subscription = props.source.subscribe();
  
  if(visible){
    subscription.unsubscribe();
}  
  return () => {
    // Clean up the subscription

  };
},[visible]);

내가 원하는 것은 componentWillUnmount의 돔의 제거 상황이 아니라 visible이란 스테잇값에 따라
unsubscribe을 하고자 하는 것이었다.

언뜻 보면 작동할 거 같아서 짜보았지만 이렇게 작업하면 unsubscribe이 작동되지 않는다.

이유는 다음과 같다.

숙련된 자바스크립트 개발자라면 useEffect에 전달된 함수가 모든 렌더링에서 다르다는 것을 알아챘을지도 모릅니다. 이는 의도된 것으로서, count 값이 제대로 업데이트 되는지에 대한 걱정 없이 effect 내부에서 그 값을 읽을 수 있게 하는 부분이기도 합니다
(https://ko.reactjs.org/docs/hooks-effect.html#explanation-why-effects-run-on-each-update)

useEffect안의 함수가 랜더링이 다시 되는 순간 const subscription = props.source.subscribe();에서 subscription은 새로 정의 된다.
즉 참조값이 다른 새로운 함수가 되는 것이다.
그래서

if(visible){ subscription.unsubscribe();} 

해봐야 우리가 원했던 subscription은 unsubscribe되지 못하고 메모리 어딘가에서 작동하고 있다.

그래서 정 componentWillUnmount의 방법이 아닌 다른 방식으로 subscription을 제거 하고 싶다면

const subRef = useRef(() => props.source)
	
useEffect(()=>{
   subRef.subscribe()
  if(visible){
    subRef.current.unsubscribe();
  }
},[])

이런 식으로 useRef를 활용해서 참조값을 그대로 유지해주면 된다.

profile
세상을 즐겁게 하고 싶은 개발자

0개의 댓글