React

useEffect완벽 가이드 클린 업

노엠디엔 2023. 9. 24. 18:49

저번에 useEffect는 어떻게 최신 상태를 읽을 수 있을까? 의 정리로 useEffect 내에서 동작하는 함수는 렌더링마다 고유한 함수이며 
그 이펙트 렌더링상태의 고유한 state와 props를 보게 되는 것!이라고
하였다.(이펙트는 렌더링 결과의 일부는 아님!)

https://zoon-bloom.tistory.com/130

 

이번에는 클리업에 대해 읽어보았는데 일단 클린업의 사용법은 다음과 같다.

클린업은  보통 컴포넌트가 원마운트되었을 때 이벤트를 제거하기 위해 사용하는 것으로 알고 있었다.

하지만! 가이드에서는 클린업이 리랜더링 되기 전에 실행되고 이전의 상태를 “보고”, 그다음 새 이펙트가 리랜더링 이후 실행되기 때문에
새로운 상태를 “본다고” 생각할 수 있지만. 이 멘탈 모델은 클래스의 라이프사이클을 그대로 옮겨 놓은 것과 같고, 잘못된 내용이라고 한다.

 

리액트는 브라우저가 페인트 하고 난 뒤에야 이펙트를 실행합니다. 이렇게 하여 대부분의 이펙트가 스크린 업데이트를 가로막지 않기 때문에 앱을 빠르게 만들어주며 마찬가지로 이펙트의 클린업도 미뤄진다고 한다. 
그러므로 이전 이펙트는 새 prop과 함께 리랜더링 되고 난 뒤에 클린업됩니다.

브라우저 페인팅 단계: 변경된 부분이 실제 DOM에 렌더링 되면 브라우저가 페인팅 과정을 시작하고 변경된 요소를 화면에 그리는 작업
브라우저는 변경된 부분만을 다시 그리고, 다른 부분은 그대로 유지한다

 

그럼 만약 해당 예제에서 count 가 1 증가되었다고 하였다면 

  • 리액트가 {count : 1}을 가지고 UI를 랜더링 한다.
  • 브라우저가 실제 그리기를 한다. 화면상에서{count: 1} 이 반영된 UI를 볼 수 있다.
  • 리액트는 {count: 0}, setInterval에 대한 이펙트를 클린 업한다.
  • 리액트가 {count: 1}, setInterval에 대한 이펙트를 실행한다.

그럼 어떻게 이펙트의 클린업이  예전 값을 볼 수 있는 걸까? 그 이유는 저번에도 살펴보았던

컴포넌트가 랜더링 안에 있는 모든 함수는 (이벤트 핸들러, 이펙트, 타임아웃이나 그 안에서 호출되는 API 등)
랜더가 호출될 때 정의된 props와 state 값을 잡아두기 때문이다.

이펙트의 클린업은 최신 상태를  읽지 않으며 클린업이 정의된 시점의 랜더링에 있던 값을 읽는 것이다.

 

이로써 모든 useEffect가 왜 그렇게 동작하는지에 대한 이유를 이제 조금이나마 이해가 될 것 같다.

브라우저가 페인트의 기능을 수행 후에 이펙트의 동작을 함으로써  이펙트가 스크린 업데이트를 가로막지 않게 되며

클린업에서도 이러한 새로운 값에 의한 브라우저의 페인팅이 이루어져야지만 동작을 한다는 것?! (맞나?..)

 

https://overreacted.io/ko/a-complete-guide-to-useeffect/

 

useEffect 완벽 가이드

이펙트는 데이터 흐름의 한 부분입니다.

overreacted.io