[ReactJS로 영화 웹 서비스 만들기 실습] useEffect clean-up

IRISH·2024년 4월 19일

ReactJS-Movie-Web-Service

목록 보기
15/23
post-thumbnail
  • 실습일자 : 2024.04.19

useEffect에서 clean-up을 사용하는 이유

React에서 'useEffect' 후크의 clean-up 기능은 메모리 누수를 방지하고 구성 요소를 마운트 해제할 때 또는 업데이트된 종속성을 사용하여 구성 요소를 다시 렌더링하기 전에 더 이상 필요하지 않은 부작용을 제거하는 데 중요합니다. 이 기능을 사용하면 애플리케이션이 효율적으로 실행되고 타이머, 구독 또는 이벤트 리스너와 같은 리소스가 적절하게 관리됩니다.

useEffect의 clean-up는 다음 용도로 사용됩니다.

  1. 메모리 누수 방지: 구성 요소가 마운트 해제될 때 리스너 또는 구독을 정리하면 이러한 리스너 또는 구독이 활성 상태로 남아 있을 때 발생할 수 있는 메모리 누수를 방지할 수 있습니다.
  2. 원치 않는 동작 방지: 관련성이 있는 경우에만 효과가 실행되도록 하면 오래된 상태 또는 소품을 캡처하는 오래된 클로저로 인해 발생하는 버그를 방지할 수 있습니다.
  3. 성능 최적화: 불필요한 리스너와 구독을 제거하면 브라우저의 작업 부하가 줄어들어 애플리케이션 성능이 향상됩니다.

clean-up의 개념

useEffect 내부에 함수를 선언하면 선택적으로 다른 함수를 반환할 수 있습니다. 이 반환된 함수는 정리 함수입니다. React는 다음과 같은 경우에 이 clean-up 기능을 실행합니다.

  • 구성요소가 마운트 해제되려고 합니다.
  • 종속성 중 하나의 변경으로 인해 구성 요소가 효과를 다시 실행하려고 합니다.

clean-up하지 않은 예

이벤트 리스너를 설정하지만 clean-up하지는 않는 구성 요소를 생각해 보세요. 구성 요소가 마운트 해제된 후에도 리스너가 계속 활성 상태인 경우 오류나 예기치 않은 동작이 발생할 수 있습니다.

import React, { useState, useEffect } from 'react';

function ExampleComponent() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => {
      setWindowWidth(window.innerWidth);
    };

    window.addEventListener('resize', handleResize);
    // No clean-up here
  }, []);  // The effect runs only on mount

  return <div>Window width: {windowWidth}</div>;
}

이 예에서는 구성요소가 마운트될 때 'handleResize'가 이벤트 리스너로 추가됩니다. 그러나 구성 요소가 마운트 해제되면 이벤트 리스너는 제거되지 않습니다. 구성 요소 인스턴스가 DOM에서 제거되면 이벤트 핸들러는 여전히 존재하지 않는 구성 요소의 상태를 업데이트하려고 시도하므로 오류가 발생할 수 있습니다.

clean-up 예시

이벤트 리스너를 제거하기 위해 clean-up를 구현하는 방법은 다음과 같습니다.

import React, { useState, useEffect } from 'react';

function ExampleComponent() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => {
      setWindowWidth(window.innerWidth);
    };

    window.addEventListener('resize', handleResize);

    // Clean-up function
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);  // The effect runs only on mount

  return <div>Window width: {windowWidth}</div>;
}

이 수정된 예에서 clean-up 함수는 구성 요소가 마운트 해제될 때 또는 효과가 다시 실행되기 전에 이벤트 리스너를 제거합니다(이 경우 종속성 배열이 비어 있기 때문에 발생하지 않습니다). 이렇게 하면 구성 요소가 마운트 해제된 후 상태를 업데이트하려고 시도하는 것을 방지하여 잠재적인 메모리 누수 및 오류를 방지할 수 있습니다.

결과 화면

  • 결과 화면은 clean-up 기능을 넣은 것이나, 넣지 않은 것 모두 동일하다.

결론

리소스를 효율적으로 관리하는 강력한 React 구성 요소를 작성하려면 useEffect에서 정리 기능을 사용하는 것이 필수적입니다. 이는 메모리 누수를 방지하는 데 도움이 되며 구성 요소가 오래된 DOM 요소 또는 데이터와 상호 작용하지 않도록 합니다.

느낀점

처음 clean-up에 대한 설명을 보았을 때, 아 좋은 기능인 것을 알겠는데 결과가 동일하게 나오는데… 도대체 무슨 효과가 있는 것인가에 대한 생각이 많이 들었다.

근데, 이러한 경우 효과가 있겠구나를 많이 생각하게 됐다.

위 코드 예시에서 handleResize 이벤트가 존재한다. 이 이벤트가 존재하는 화면명이 A라고 하자.

A에서 B라는 화면으로 넘어갈 때, clean-up 기능이 있을 경우 아무 문제가 없다. 하지만, clean-up 기능이 없다면?

B 화면으로 넘어가도 handleResize 이벤트가 리스너에 남아 있을 수도 있다. 그럴 경우, B 안에서는 handleResize 가 없지만, 리스너 자체에는 handleResize 가 남아 있는 상태가 발생할 수도 있다. 즉, A 화면이 아님에도 불구하고 handleResize 가 돌아가고 있을 수도 있다는 것. 이러한 상태에서는 에러가 발생할 수 있다.

따라서, useEffect 안에서 clean-up을 사용해 에러가 발생하지 않도록 하는 것이 오늘 배움의 key-point라고 할 수 있다.

참고

profile
#Software Engineer #IRISH

0개의 댓글