useEffect ?

React 컴포넌트가 렌더링될 때마다 특정 작업(Side effect)을 실행할 수 있도록 하는 리액트 Hook이다. 여기서 side effect란 컴포넌트가 렌더링된 후 처리되어야 하는 부수적인 효과들을 말하며, 컴포넌트가 렌더링된 이후 비동기적으로 처리되는 작업들을 일컫는다. 이를 통해 함수형 컴포넌트에서도 클래스형 컴포넌트에서 쓰던 생명주기 메소드들(ex : componentDidMount)들을 쓸 수 있게 됐다.

useEffect는 실행되면 인자로 받은 콜백을 예약해뒀다가, 컴포넌트가 렌더링되면 예약해둔 콜백을 실행한다.

 

기본적인 형태

useEffect(function, deps);

// ex
useEffect(() => {
  document.title = `총 ${count}개`;
}, [count]);

function : 실행하고자 하는 함수 즉 side effect

deps : 의존성 배열. 이 배열 안의 값이 변경되는 경우에만 side effect가 실행됨. 빈 배열을 줄 경우 해당 컴포넌트가 최초 렌더링될때만(즉 생성될 때만) side effect가 실행되고, 배열 자체를 주지 않을 경우 컴포넌트가 렌더링될때마다 side effect가 수행됨.

 

※ 여기서 말하는 컴포넌트란 useEffect가 작성된 컴포넌트를 말함

 

 

Advanced

1. deps의 종류에 따른 side effect 수행

  • deps로 뭔가 값이 들어있는 배열을 준 경우 : 컴포넌트가 마운트될때(생성될 때)와 deps배열에 작성된 값들이 변경될 때만 side effect가 실행
  • deps로 빈 배열을 준 경우 : 컴포넌트가 마운트될때만 side effect가 실행 (ComponentDidMount만 표현한 느낌)
  • deps로 아무것도 주지 않은 경우 : 컴포넌트가 마운트될때, 컴포넌트가 렌더링될 때마다 side effect가 수행됨(ComponentDidMount와 ComponentDidUpdate를 표현한 느낌)

 

※좀 더 정확히 설명하면..

  1.  컴포넌트가 마운트될 때 콜백을 예약하고 deps 리스트 안의 값들을 기억함. 이후 콜백을 실행.
  2.  state변경 등으로 컴포넌트가 리렌더링되면 useEffect가 다시 실행됨. 이 때 새로 실행되는 useEffect의 deps 리스트 안의 값들을 전에 기억해두고 있던 deps 리스트의 값들과 비교
  3.  달라진 게 있다면 새로 실행된 useEffect의 콜백을 예약하고 렌더링이 끝나면 실행함. 그러나 달라진 게 없으면 콜백을 예약하지 않음(즉 렌더링 끝나도 실행되지 않음).
  4.  때문에 deps를 빈 배열로 주면 항상 전에 기억하던 것과 같은 거니까 이후에 다시 컴포넌트가 렌더링되도 콜백을 수행하지 않음 즉 최초 마운트할 때만 실행하는 꼴이 됨. deps안에 내용물이 뭔가 있을 때, 컴포넌트가 리렌더링되도 deps값이 변한 게 없으면 콜백을 실행하지 않음 즉 deps안의 값이 변경될 경우에만 콜백(side effect)가 실행되는 꼴

 

2. 컴포넌트가 unmount될때 수행할 side effect (clean up)

: side effect로 작성한 함수에서 특정 함수를 return하게 하면 clean up기능을 사용할 수 있다. 덕분에 컴포넌트가 unmount될 시 리턴하는 함수가 실행되게 할 수 있다. useEffect를 통한 side effect는 여러 번 실행될 수 있기 때문에 메모리 누수 등을 막기 위해 이런 clean up이 필요한 경우가 많다. 참고로 컴포넌트가 unmount될 때 실행되므로 컴포넌트가 업데이트될 때(리렌더링될 때)에도 수행된다. 이 경우는 리렌더링이 먼저 된 후 clean up이 수행되고, 새로운 side effect가 실행된다. 즉 useEffect에서 clean up의 동작 순서는

 

  1. props나 state가 update됨
  2. 컴포넌트가 리렌더링됨
  3. 이전 side effect의 clean up이 수행
  4. 새로운 side effect 수행

 

이다.

 

※ clean up을 쓰는 또 다른 이유

: 클로저 때문이다. useEffect에서 side effect로 주는 함수는 자기가 생성될 때의 값을 바라보기 때문. 즉 side effect내에서 참조하는 state가 가장 최신의 state가 아닐 수도 있다. 이 때 clean up이 있다면 과거의 변수 값을 참조하던 effect가 정리되고 새로운 변수 값을 다시 참조할 수 있게 된다. 

 

 

+ Recent posts