v19.2Latest

렌더링과 커밋

컴포넌트가 화면에 표시되기 전에 React에 의해 렌더링되어야 합니다. 이 과정의 단계를 이해하면 코드가 어떻게 실행되는지 생각하고 그 동작을 설명하는 데 도움이 됩니다.

배울 내용
  • React에서 렌더링이 의미하는 것
  • React가 컴포넌트를 렌더링하는 시기와 이유
  • 컴포넌트를 화면에 표시하는 데 관련된 단계
  • 렌더링이 항상 DOM 업데이트를 생성하지 않는 이유

컴포넌트가 주방에서 재료로 맛있는 요리를 조립하는 요리사라고 상상해 보세요. 이 시나리오에서 React는 고객의 주문을 받아서 가져다 주는 웨이터입니다. UI를 요청하고 제공하는 이 과정에는 세 단계가 있습니다:

  1. 트리거렌더링 (손님의 주문을 주방에 전달)
  2. 렌더링컴포넌트 (주방에서 주문 준비)
  3. 커밋DOM에 (테이블에 주문 배치)
  1. 레스토랑의 서버 역할을 하는 React가 사용자로부터 주문을 가져와 컴포넌트 주방에 전달합니다.트리거
  2. 카드 셰프가 React에게 새로운 카드 컴포넌트를 제공합니다.렌더링
  3. React가 카드를 사용자의 테이블에 전달합니다.커밋

일러스트레이션:Rachel Lee Nabors

1단계: 렌더링 트리거하기

컴포넌트가 렌더링되는 데는 두 가지 이유가 있습니다:

  1. 컴포넌트의 초기 렌더링입니다.
  2. 컴포넌트(또는 그 조상 중 하나)의상태가 업데이트되었습니다.

초기 렌더링

앱이 시작될 때 초기 렌더링을 트리거해야 합니다. 프레임워크와 샌드박스는 때때로 이 코드를 숨기지만, 대상 DOM 노드로createRoot를 호출한 다음 해당 render메서드를 컴포넌트와 함께 호출하여 수행됩니다:

주석 처리해 보세요root.render()호출을 주석 처리하면 컴포넌트가 사라지는 것을 확인할 수 있습니다!

상태 업데이트 시 다시 렌더링

컴포넌트가 초기 렌더링된 후에는 set 함수를 사용하여 상태를 업데이트함으로써 추가 렌더링을 트리거할 수 있습니다. 컴포넌트의 상태를 업데이트하면 자동으로 렌더링이 큐에 들어갑니다. (이를 식당 손님이 첫 주문을 한 후 목마름이나 배고픔 상태에 따라 차, 디저트, 다양한 음식을 추가로 주문하는 것처럼 상상할 수 있습니다.)

  1. 레스토랑의 서버 역할을 하는 React가 사용자에게 Card UI를 제공하고 있습니다. 사용자는 커서 머리를 가진 손님으로 표현되어 있으며, 검은색 카드가 아닌 분홍색 카드를 원한다고 말하고 있습니다!상태 업데이트...
  2. React가 컴포넌트 주방으로 돌아가 Card 요리사에게 분홍색 Card가 필요하다고 알립니다....트리거...
  3. Card 요리사가 React에게 분홍색 Card를 건네줍니다....렌더링!

일러스트:Rachel Lee Nabors

2단계: React가 컴포넌트를 렌더링합니다

렌더링을 트리거한 후, React는 화면에 무엇을 표시할지 결정하기 위해 컴포넌트를 호출합니다."렌더링"은 React가 컴포넌트를 호출하는 것입니다.

  • 초기 렌더링 시,React는 루트 컴포넌트를 호출합니다.
  • 이후 렌더링에서는,상태 업데이트를 트리거한 함수 컴포넌트를 호출합니다.

이 과정은 재귀적입니다: 업데이트된 컴포넌트가 다른 컴포넌트를 반환하면 React는 다음으로컴포넌트를 렌더링하고, 해당 컴포넌트도 무언가를 반환하면 다음으로컴포넌트를 렌더링하는 식으로 진행됩니다. 더 이상 중첩된 컴포넌트가 없고 React가 화면에 정확히 무엇을 표시해야 할지 알 때까지 이 과정이 계속됩니다.

다음 예제에서 React는Gallery()Image()를 여러 번 호출합니다:

  • 초기 렌더링 동안,React는DOM 노드를 생성합니다 <section>,<h1>, 그리고 세 개의<img>태그에 대해.
  • 재렌더링 동안,React는 이전 렌더링 이후 어떤 속성이 변경되었는지 계산합니다. 이 정보는 다음 단계인 커밋 단계까지는 아무 작업도 수행하지 않습니다.
주의사항

렌더링은 항상 순수 계산이어야 합니다:

  • 동일한 입력, 동일한 출력.동일한 입력이 주어지면 컴포넌트는 항상 동일한 JSX를 반환해야 합니다. (누군가 토마토가 들어간 샐러드를 주문했다면 양파가 들어간 샐러드를 받아서는 안 됩니다!)
  • 자신의 일에만 집중합니다.렌더링 전에 존재했던 객체나 변수를 변경해서는 안 됩니다. (한 주문이 다른 사람의 주문을 변경해서는 안 됩니다.)

그렇지 않으면 코드베이스가 복잡해짐에 따라 혼란스러운 버그와 예측할 수 없는 동작을 마주할 수 있습니다. "엄격 모드"에서 개발할 때 React는 각 컴포넌트 함수를 두 번 호출하는데, 이는 순수하지 않은 함수로 인한 실수를 드러내는 데 도움이 될 수 있습니다.

Deep Dive
성능 최적화

3단계: React가 변경 사항을 DOM에 커밋합니다

컴포넌트를 렌더링(호출)한 후, React는 DOM을 수정합니다.

  • 초기 렌더링 시,React는 생성한 모든 DOM 노드를 화면에 표시하기 위해appendChild() DOM API를 사용합니다.
  • 재렌더링 시,React는 DOM이 최신 렌더링 출력과 일치하도록 (렌더링 중 계산된!) 최소한의 필요한 작업을 적용합니다.

React는 렌더링 간에 차이가 있을 때만 DOM 노드를 변경합니다.예를 들어, 다음은 부모 컴포넌트로부터 매초 다른 props를 전달받아 재렌더링되는 컴포넌트입니다.<input>에 텍스트를 추가하여 그value를 업데이트해도, 컴포넌트가 재렌더링될 때 텍스트가 사라지지 않는 것을 확인할 수 있습니다:

이는 마지막 단계에서 React가 새로운 <h1>의 내용만time으로 업데이트하기 때문에 작동합니다. React는<input>이 JSX에서 이전과 동일한 위치에 나타나는 것을 확인하므로,<input>이나 그value를 건드리지 않습니다!

에필로그: 브라우저 페인팅

렌더링이 완료되고 React가 DOM을 업데이트한 후, 브라우저는 화면을 다시 그립니다. 이 과정은 일반적으로 "브라우저 렌더링"으로 알려져 있지만, 문서 전체에서 혼동을 피하기 위해 "페인팅"이라고 부르겠습니다.

브라우저가 '카드 요소가 있는 정물화'를 그리고 있습니다.

일러스트:Rachel Lee Nabors

요약

  • React 앱에서 화면 업데이트는 세 단계로 이루어집니다:
    1. 트리거
    2. 렌더
    3. 커밋
  • Strict Mode를 사용하여 컴포넌트의 실수를 찾을 수 있습니다
  • 렌더링 결과가 이전과 동일하면 React는 DOM을 건드리지 않습니다