정답: A 1
, C 0
, B 1
이 순서대로 출력된다.
You clicked 0 times
Console
이전 렌더링의 클린업은 다음 렌더링의 컴포넌트가 브라우저에 그려진 이후에 실행된다.
각 렌더링마다 코드들이 어떤 순서대로 실행되는지 자세하게 알아보겠다.
-
첫 번째 렌더링
- 컴포넌트 내부의 코드가 실행된다. 즉,
count
,setCount
가 정의되고 콘솔에A 0
이 출력된다. - 렌더링 결과물인
<p>You clicked 0 times</p>...
가 화면에 그려진다. useEffect
의 셋업이 실행된다. 즉, 콘솔에B 0
이 출력된다.
- 컴포넌트 내부의 코드가 실행된다. 즉,
-
(버튼을 클릭하여) 두 번째 렌더링
- 컴포넌트 내부의 코드가 실행된다. 즉,
count
,setCount
가 정의되고 콘솔에A 1
이 출력된다. - 렌더링 결과물인
<p>You clicked 1 times</p>...
가 화면에 그려진다. useEffect
의 클린업이 실행된다. 즉, 콘솔에C 0
이 출력된다.useEffect
의 셋업이 실행된다. 즉, 콘솔에B 1
이 출력된다.
- 컴포넌트 내부의 코드가 실행된다. 즉,
-
(버튼을 한 번 더 클릭하여) 세 번째 렌더링
- 컴포넌트 내부의 코드가 실행된다. 즉,
count
,setCount
가 정의되고 콘솔에A 2
이 출력된다. - 렌더링 결과물인
<p>You clicked 2 times</p>...
가 화면에 그려진다. useEffect
의 클린업이 실행된다. 즉, 콘솔에C 1
이 출력된다.useEffect
의 셋업이 실행된다. 즉, 콘솔에B 2
이 출력된다.
- 컴포넌트 내부의 코드가 실행된다. 즉,
...
이처럼 리액트는 항상 페인팅 이후 useEffect
를 다룬다. 이펙트가 스크린 업데이트를 가로막지 않기 때문에 앱을 더 빠르게 만들어준다.
예를 들어 위와 같이 코드를 짜면 입력한 글자가 (아무 짧은 시간 동안이지만) 화면에 보인다는 것을 확인할 수 있다. 이 역시 리액트가 페인팅 이후에 useEffect
를 처리하기 때문이다.
참고로 개발 환경에서 해당 컴포넌트의 동작은 다음과 같다.
- 맨 처음에 마운트되면 콘솔에
A 0
,A 0
,B 0
,C 0
,B 0
을 출력한다. - 버튼을 한 번 누르면 콘솔에
A 1
,A 1
,C 0
,B 1
을 출력한다. - 버튼을 한 번 누르면 콘솔에
A 2
,A 2
,C 1
,B 2
을 출력한다. - ...
배포 환경과 다르게 개발 환경에서 더 많은 출력이 생기는 이유는 다음의 두 규칙을 통해 이해할 수 있다. Strict Mode가 활성화 되어있을 경우,
- 리액트는 컴포넌트가 순수 함수(pure function)인지 확인하기 쉽도록 하기 위해 기본적으로 렌더링을 2번씩 진행한다.
- 리액트는
useEffect
의 셋업 및 클린업 로직이 잘 작성되었는지 확인하기 쉽도록 하기 위해 실제 셋업 이전에 한 번씩의 셋업과 클린업을 추가적으로 실행한다.
참고자료