[TIL] 20210513_React Hook_part2

BANSEOK SUH·2021년 5월 13일
0

TIL

목록 보기
14/22
post-thumbnail

Effect Hook의 cleanup

React Hook_part1에서는 useState와 useEffect 메서드를 살펴보았습니다.
특히 useState 메서드를 사용하여 함수 컴포넌트에서 state를 관리하는 방법, useEffect와 그것의 두 번째 인자를 사용하여 특정 state에 변화가 생길 때에만 useEffect가 실행되도록 하는 방법을 살펴봤지요.

이번에는 useEffect 메서드 사용 시 cleanup이 필요한 경우를 살펴보겠습니다.
(part1에서는 cleanup이 필요하지 않았습니다!)

React Hook_part1 으로 이동하기

cleanup 함수

useEffect 메서드의 인자로 지정한 함수의 리턴 함수를 말합니다.

컴포넌트가 화면에서 사라지기 전, update 직전에 어떤 작업을 수행하고 싶다면 cleanUp 함수를 리턴해줘야 합니다. useEffect에 대한 뒷정리를 해주는 함수라고 이해하면 될 것 같습니다. class 컴포넌트의 경우에는 componentWillUnmount 메서드가 그 역할을 했죠.


🧐 그렇다면 이 함수는 어느 때에 적합하게 사용될 수 있을까요?


주로 다음과 같은 작업을 진행할 때에 사용된다고 합니다.
  1. setInterval, setTimeout 을 사용하여 등록한 작업들 clear 하기 (clearInterval, clearTimeout)
  2. 라이브러리 인스턴스 제거

아직은 실감이 나지 않습니다. 간단한 예시를 통해서 살펴보겠습니다.

cleanup 함수를 작성하지 않았을 시

아래의 컴포넌트는 마우스가 움직일 때의 좌표를 보여주는 컴포넌트입니다. 마우스가 이동할 때마가 이벤트가 발생되죠.

(아래 코드에는 작성되지 않았지만) Toggle display라는 버튼을 클릭하면 아래의 컴포넌트는 화면에서 사라집니다. unmount가 되는 것이지요.

function HookMouse() {
  ...

  // cleanup을 하지 않았습니다.
  useEffect(() => {
    console.log("useEffect called");
    window.addEventListener("mousemove", logMousePosition);
  }, []);

  ...
}

export default HookMouse;

!!! 컴포넌트가 화면에서 사라질 때 cleanup을 해주지 않았을 경우입니다.

아래의 영상에서는 마우스가 잘 보이지 않습니다만, 마우스가 이동하다가 버튼을 클릭합니다!

버튼 클릭 시에 컴포넌트는 사라졌지만(unmount), 이벤트는 여전히 작동하고 있습니다. 다음과 같은 에러와 함께 말이죠.

"Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function."

"경고: 마운트가 해제된 컴포넌트에서는 리액트 상태 업데이트를 수행할 수 없습니다. 이것은 작동하지 않지만, 이건 당신의 애플리케이션에서의 메모리 누수를 나타냅니다. 수정하려면 useEffect cleanup 함수에서 모든 구독과 비동기 작업을 취소하십시오."


cleanup 함수를 작성하지 않으니 브라우저에서는 친절하게 알려주는군요.
위의 경고에서 알려준 것처럼 cleanup 함수를 작성하고, 함수 안에서 필요한 작업을 진행해보겠습니다.


cleanup 함수를 작성했을 시

!!! 다음은 useEffect 함수에서 cleanup 함수를 작성한 경우입니다.

cleanup 함수가 무엇이라고 했죠? useEffect의 인자로 받아온 함수의 리턴 함수라고 했습니다.

cleanup 함수를 작성하고, 그 안에서 마우스 이벤트를 해제시켜보겠습니다.

function HookMouse() {
  ...
  useEffect(() => {
    console.log("useEffect called");
    window.addEventListener("mousemove", logMousePosition);
    // 인자 함수의 리턴 함수를 정의합니다. --- cleanup 함수 작성
    // 함수 내부에서 이벤트를 해제합니다.  --- 필요한 작업
    return () => {
      console.log("Component unmount code");
      window.removeEventListener("mousemove", logMousePosition);
    };
  }, []);

  ...
}

마우스가 움직이다가 버튼을 클릭합니다. 컴포넌트가 사라졌습니다!

버튼 클릭 시에 cleanup 함수 내부의 로그('Component unmount code')가 찍히는 것을 볼 수 있습니다.
컴포넌트가 화면에서 사라지기(unmount) 전에 수행됐다는 것을 알 수 있습니다.

또한 에러가 나지 않는 것으로 보아, cleanup 함수 안에서 이벤트 함수가 정상적으로 해제됐다는 것을 확인할 수 있네요.


아직은 cleanup 함수가 어떤 경우에 매우 유용하게 사용될 지 실감이 나지 않지만,

다만 기억해야 할 것은 다음과 같습니다.

  1. cleanup 함수는 useEffect 메서드의 인자함수의 리턴함수입니다.
  2. cleanup 함수는 컴포넌트가 화면에서 사라질 때(unmount) 수행됩니다.
  3. cleanup 함수는 컴포넌트 제거 전 setInterval, setTimeout 등의 작업들을 clear해야 할 때, 라이브러리 인스턴스를 제거해야 할 때 유용하게 사용됩니다.
profile
HelloBanny

0개의 댓글