React의 렌더링 과정과 useEffect의 실행 순서

민주니어·2024년 7월 20일
post-thumbnail

렌더링 과정

  • 초기 렌더링: 컴포넌트가 처음 화면에 나타날 때 발생
    React는 컴포넌트의 render 함수를 호출하여 JSX를 생성하고, 이를 바탕으로 가상 DOM을 만든 후 실제 DOM에 반영한다.
  • 리렌더링: 컴포넌트의 상태나 속성이 변경될 때 일어난다
    이때 React는 새로운 가상 DOM을 생성하고 이전 것과 비교하여 실제로 변경된 부분만 DOM에 적용한다. 이 과정을 통해 효율적인 UI 업데이트가 가능해진다.

렌더링 단계

React 공식 페이지에서는 react의 렌더링 과정을 레스토랑의 주문-요리-서빙 과정에 비유하여 설명하고 있다

  1. 렌더링 트리거하기 (손님의 주문을 주방에 전달하기)
  2. 컴포넌트 렌더링하기 (주방에서 주문 준비하기)
  3. DOM에 커밋하기 (테이블에 주문한 음식 올려놓기)

렌더링 과정의 두 주요 단계

  • 렌더 단계(Render Phase): 변경사항을 계산만 하고 실제 DOM에는 아무 영향을 주지 않는다.
    이 단계는 비동기적으로 실행될 수 있으며, 필요에 따라 중단되거나 재시작될 수 있다.
  • 커밋 단계: 계산된 변경사항을 실제 DOM에 적용한다. 이 단계는 동기적으로 실행되며 중단될 수 없다

렌더 단계(Render Phase)

가상 DOM을 생성하고 변경 사항을 계산하는 단계

특징

  • 순수(pure)하고 부수 효과(Side Effect)가 없다
  • 비동기적으로 실행될 수 있다
  • 필요에 따라 중단되거나 재시작될 수 있다

주요 과정

1) 컴포넌트 함수 호출: React는 컴포넌트 함수를 호출하여 새로운 React element tree(가상 DOM)를 생성한다.
2) 재조정(Reconciliation): 새로 생성된 엘리먼트 트리와 이전 트리를 비교하여 변경사항을 파악한다.
3) 변경 사항 계산: 어떤 DOM 노드를 추가, 수정, 또는 제거해야 하는지 결정한다

최적화

렌더 단계에서는 실제 DOM을 건드리지 않기 때문에, React는 이 단계를 여러 번 수행할 수 있다
무거운 계산이나 복잡한 로직은 이 단계에서 피하는 것이 좋다

커밋 단계 (Commit Phase)

렌더 단계에서 계산된 변경사항을 실제 DOM에 적용하는 단계

특징

  • 동기적으로 실행
  • 한 번 시작되면 중단될 수 없다
  • DOM 조작과 같은 부수 효과를 포함한다

주요 과정

1) DOM 업데이트: 렌더 단계에서 계산된 변경사항을 실제 DOM에 적용한다
2) 라이프사이클 메서드 호출: componentDidMount, componentDidUpdate와 같은 생명주기 메서드를 호출한다
3) ref 업데이트: ref를 통해 DOM 노드나 컴포넌트 인스턴스에 대한 참조를 업데이트한다

최적화

커밋 단계는 비용이 많이 들기 때문에, React는 이 단계를 최소한으로 유지하려고 한다
DOM 조작을 최소화하고, 가능한 한 적은 변경사항만 적용하는 것이 좋다

💻 렌더 단계와 커밋 단계의 관계
렌더 단계가 먼저 실행되고, 그 다음 커밋 단계가 실행된다
렌더 단계는 "무엇을 변경할지" 결정하는 단계이고,
커밋 단계는 "실제로 변경을 적용하는" 단계이다
렌더 단계는 여러 번 실행되어도 큰 문제가 없지만, 커밋 단계는 실제 DOM을 변경하므로 성능에 직접적인 영향을 준다

useEffect의 역할

useEffect는 React의 함수형 컴포넌트에서 부수 효과를 처리하기 위한 hook이다
데이터 페칭, 구독 설정, DOM 직접 조작 등의 작업에 사용된다

useEffect의 실행 순서

useEffect는 렌더링 과정이 완전히 끝나고 화면이 업데이트된 후에 실행된다

❗ 구체적인 실행 순서
1. 렌더 단계
2. 커밋 단계
3. 브라우저의 화면 그리기
4. useEffect 실행

이런 순서로 실행되는 이유는 렌더링을 빠르게 완료하여 사용자에게 UI를 신속하게 보여주고,
useEffect 내의 부수 효과가 렌더링 결과에 즉각적인 영향을 주지 않도록 하기 위함이다

useEffect의 특징

useEffect는 의존성 배열을 통해 실행 시점을 제어할 수 있다
빈 배열을 전달하면 컴포넌트 마운트 시에만 실행되고, 특정 값을 포함시키면 해당 값이 변경될 때마다 실행된다. 배열을 생략하면 매 렌더링마다 실행된다

또한 useEffect는 클린업 함수를 반환할 수 있어, 컴포넌트가 언마운트되거나 다음 효과가 실행되기 전에 필요한 정리 작업을 수행할 수 있다

참고 자료

profile
drop the bit

0개의 댓글