React가 리렌더링(Re-render)이라고 말할 때, 그것은 세 가지를 의미합니다

setState를 호출할 때 React는 단순히 DOM을 업데이트하는 것이 아닙니다. React는 세 가지 별도의 단계를 순차적으로 실행합니다. 대부분의 개발자가 이 단계들을 혼동하곤 합니다. 이 차이를 이해하면 성능 문제를 해결하는 데 도움이 됩니다.

세 가지 단계:

• Render: React가 컴포넌트 함수를 호출합니다. • Reconcile: React가 새로운 출력값과 이전 출력값을 비교합니다. • Commit: React가 변경 사항을 DOM에 적용합니다.

  1. Render 단계

React가 함수를 실행합니다. 현재의 props를 사용합니다. 함수는 JSX를 반환합니다. 이 JSX는 단순히 JavaScript 객체들의 목록입니다. 사람들은 이를 virtual DOM이라고 부릅니다. 이것은 실제 DOM이 아닙니다. UI가 어떻게 보여야 하는지에 대한 기술(description)입니다. 아직 화면에는 아무것도 나타나지 않습니다. 이 단계는 순수한 수학과 로직의 영역입니다.

  1. Reconcile 단계

React는 이전 트리와 새로운 트리를 모두 가지고 있습니다. 그리고 그 사이의 차이점을 찾습니다. 만약 요소의 타입(type)이 변경되면, React는 트리 전체를 교체합니다. 만약 props만 변경되었다면, React는 이를 업데이트합니다. 여기서 key가 중요해집니다. key는 React가 리스트의 아이템을 위치가 아닌 식별자(identity)를 기준으로 매칭할 수 있도록 도와줍니다. 이 단계에서는 DOM을 업데이트하는 데 필요한 최소한의 단계 목록을 생성합니다.

  1. Commit 단계

React는 변경 사항 목록을 가져와 실제 DOM을 조작합니다. 새로운 노드를 생성하고 오래된 노드를 제거합니다. 사용자가 화면에서 변화를 목격하는 시점이 바로 이때입니다. 이 작업이 끝난 후 브라우저가 화면을 그립니다(paint). 그 다음에 useEffect가 실행됩니다.

흔한 오해들:

• 리렌더링이 항상 DOM을 변경하는 것은 아닙니다. 출력값이 동일하다면, React는 commit 단계에서 아무것도 하지 않습니다. • React.memo는 함수 호출을 건너뛰는 것이지, DOM 업데이트를 건너뛰는 것이 아닙니다. • props가 리렌더링을 트리거하는 것이 아닙니다. 부모 컴포넌트의 리렌더링이 자식 컴포넌트를 트리거하는 것이며, props의 변경은 그 결과일 뿐입니다.

성능을 개선하는 방법:

함수 실행이 느리다면 Render 문제입니다. 무거운 작업을 함수 밖으로 옮기거나 memoization을 사용하세요.

React가 거대한 리스트를 다시 빌드한다면 Reconcile 문제입니다. key를 확인하세요.

DOM 업데이트가 너무 빈번하다면 Commit 문제입니다. virtualization을 사용하거나 구조를 변경하세요.

React 19와 React Compiler가 이제 이러한 작업의 상당 부분을 대신 처리해 줍니다. 하지만 이 단계들을 알고 있으면 디버깅을 더 잘할 수 있습니다.

Source: https://dev.to/dip_032d2fe1959e1990ddbb1/when-react-says-re-render-it-actually-means-three-things-11d7