React 공식 페이지에서는 react의 렌더링 과정을 레스토랑의 주문-요리-서빙 과정에 비유하여 설명하고 있다
가상 DOM을 생성하고 변경 사항을 계산하는 단계
1) 컴포넌트 함수 호출: React는 컴포넌트 함수를 호출하여 새로운 React element tree(가상 DOM)를 생성한다.
2) 재조정(Reconciliation): 새로 생성된 엘리먼트 트리와 이전 트리를 비교하여 변경사항을 파악한다.
3) 변경 사항 계산: 어떤 DOM 노드를 추가, 수정, 또는 제거해야 하는지 결정한다
렌더 단계에서는 실제 DOM을 건드리지 않기 때문에, React는 이 단계를 여러 번 수행할 수 있다
무거운 계산이나 복잡한 로직은 이 단계에서 피하는 것이 좋다
렌더 단계에서 계산된 변경사항을 실제 DOM에 적용하는 단계
1) DOM 업데이트: 렌더 단계에서 계산된 변경사항을 실제 DOM에 적용한다
2) 라이프사이클 메서드 호출: componentDidMount, componentDidUpdate와 같은 생명주기 메서드를 호출한다
3) ref 업데이트: ref를 통해 DOM 노드나 컴포넌트 인스턴스에 대한 참조를 업데이트한다
커밋 단계는 비용이 많이 들기 때문에, React는 이 단계를 최소한으로 유지하려고 한다
DOM 조작을 최소화하고, 가능한 한 적은 변경사항만 적용하는 것이 좋다
💻 렌더 단계와 커밋 단계의 관계
렌더 단계가 먼저 실행되고, 그 다음 커밋 단계가 실행된다
렌더 단계는 "무엇을 변경할지" 결정하는 단계이고,
커밋 단계는 "실제로 변경을 적용하는" 단계이다
렌더 단계는 여러 번 실행되어도 큰 문제가 없지만, 커밋 단계는 실제 DOM을 변경하므로 성능에 직접적인 영향을 준다
useEffect는 React의 함수형 컴포넌트에서 부수 효과를 처리하기 위한 hook이다
데이터 페칭, 구독 설정, DOM 직접 조작 등의 작업에 사용된다
useEffect는 렌더링 과정이 완전히 끝나고 화면이 업데이트된 후에 실행된다
❗ 구체적인 실행 순서
1. 렌더 단계
2. 커밋 단계
3. 브라우저의 화면 그리기
4. useEffect 실행
이런 순서로 실행되는 이유는 렌더링을 빠르게 완료하여 사용자에게 UI를 신속하게 보여주고,
useEffect 내의 부수 효과가 렌더링 결과에 즉각적인 영향을 주지 않도록 하기 위함이다
useEffect는 의존성 배열을 통해 실행 시점을 제어할 수 있다
빈 배열을 전달하면 컴포넌트 마운트 시에만 실행되고, 특정 값을 포함시키면 해당 값이 변경될 때마다 실행된다. 배열을 생략하면 매 렌더링마다 실행된다
또한 useEffect는 클린업 함수를 반환할 수 있어, 컴포넌트가 언마운트되거나 다음 효과가 실행되기 전에 필요한 정리 작업을 수행할 수 있다
참고 자료
- render와 커밋
https://react.dev/learn/render-and-commit