useEffect

1. 왜 사용할까?

함수 컴포넌트는 클래스 컴포넌트와 같은 기능을 제공하지 않는다. 여기서 말하는 기능은 componentDidMount, componentDidUpdate, componentWillUnmount 와 같은 것을 말한다.

예를 들어서 React 요소에 접근하여 요소를 조작한다는 가정을 해보자. React 요소는 실제 DOM 요소가 아니기 때문에 렌더링 된 이후에 요소에 접근이 가능하다. 클래스 컴포넌트는 componentDidMount 메서드를 사용해서 접근이 가능하지만 함수 컴포넌트는 불가능하다.

이때 함수에서 클래스 컴포넌트가 갖고 있는 라이프 사이클 메서드와 같은 기능을 사용하기 위해서 useEffect를 사용할 수 있다.

1.2 언제 사용할까?

React 앱에서 데이터를 서버로부터 가져와 패치(Fetch) 해야 하거나, 실제 DOM 노드에 접근해 조작해야 하는 경우에 사용할 수 있다.

2. 사이드 이펙트

사이드 이펙트(Side Effect)는 부작용이라는 뜻이다. useEffect를 사이드 이펙트라고 하는데 왜 부작용이라고 할까?

위에서 설명 했듯이 원래 함수가 사용할 수 없는 기능을 억지로 사용하도록 만든 것이기 때문이다. 즉, componentDidMount와 같은 기능을 "원래" 사용할 수 없지만 부작용을 주어 사용할 수 있도록 만든 것이다.

2.1 참고 그림

2.2 예제

3. 라이프 사이클 훅

함수형 컴포넌트의 useEffect 훅은 클래스 컴포넌트의 다음의 라이프 사이클 훅을 하나의 API로 통합한 것이다.

  • componentDidMount

  • componentDidUpdate

  • componentWillUnmount

클래스 컴포넌트의 라이프 사이클 시점이 useEffect 내부에서 언제 실행 되는지 확인 해보자.

useEffect()에서 라이프 사이클 훅 시점을 확인 할 수 있댜.

4. Clean up

useEffect를 사용할 때 반드시 기억해야 하는 것이 바로 Clean Up이다. Clean Up은 useEffect에서 설정된 사이드 이펙트(부작용)를 해제한다.

컴포넌트가 파괴 될 때, componentDidMount 시점에 실행한 함수를 Clean Up에서 해제하지 않으면 내부의 함수가 계속해서 실행되기 때문이다.

Clean Up은 주로 이벤트 함수를 useEffect 내부에서 실행 했을 때 사용한다.

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

5. 조건부 실행

useEffect의 두번째 인자로 종속성 배열을 전달할 수 있다. 함수 컴포넌트는 렌더링 될 때마다 내부의 모든 코드를 다시 실행하기 때문에 불필요한 실행을 하지 않도록 조건처리 해야한다.

이를 구현하기 위해서 종속성 배열을 설정한다. useEffect에 종속성 배열을 설정하면 그 중 하나가 변경 되었을 때만 useEffect가 실행되기 때문에 성능 최적화에 도움을 준다.

특정 데이터만 사이드 이펙트를 설정

종속성 배열이 없을 경우 → 컴포넌트가 렌더링 될 때마다 실행 종속성 배열이 [](빈배열)일 경우 → 컴포넌트가 렌더링 될 때 최초 1번만 실행

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

6. 결론

  • useEffect는 함수 컴포넌트에서 렌더링 이후 시점에 어떤 작업을 하고 싶을 때 사용한다.

  • 컴포넌트 리 렌더링 시 불필요한 useEffect 실행을 방지하기 위해 종속성 배열을 설정한다. (변경 되었는지 비교하는 비교 군이 된다.)

  • 이벤트 함수를 내부에 사용했다면 반드시 clean up에서 함수를 정리할 로직을 걸어준다. (변경이 감지되면 실행, 그래서 실행이 아닌 참조되어 있는 상태 )

Last updated

Was this helpful?