저번에 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
'React' 카테고리의 다른 글
SOLID 하게 만들기 (0) | 2023.12.21 |
---|---|
React 완벽가이드 useEffect는 어떻게 최신상태를 읽을까? (0) | 2023.09.21 |
리액트 useEffect 완벽가이드 props와 state (0) | 2023.09.21 |
useEffect 내에서 async await (0) | 2023.09.07 |
리액트 Ref 와 DOM (0) | 2023.08.31 |