🌳 렌더링(rendering)
리액트에 존재하는 컴포넌트들이 현재 자신이 가지고 있는 props와 state의 값을 기반으로 UI를 어떻게 구성하고,
구성한 UI를 바탕으로 브라우저에게 어떤 결과를 제공할 것인지 계산하는 일련의 과정입니다.
리액트의 렌더링 과정은 크게 렌더 단계와 커밋 단계로 나눌 수 있습니다.
- 랜더 단계(render phase)
- 컴포넌트를 실행한 결과와 이전의 가상 돔을 비교한 뒤, 변경이 발생하여 렌더링이 필요한 컴포넌트를 체크
- 커밋 단계(commit phase)
- 렌더 단계에서 체크한 변경 사항들을 실제 돔에 적용하여 사용자에게 보여줌
리액트에서 렌더링이 일어나는 경우는 다음과 같습니다.
- 최초 렌더링
- 재렌더링(re-rendering)
- 클래스형 컴포넌트의 setState가 실행되는 = state가 변경되는 경우
- 클래스형 컴포넌트의 forceUpdate가 실행되는 경우
- 함수형 컴포넌트의 useState의 setter 함수가 실행되는 경우
- 함수형 컴포넌트의 useReducer의 dispatch가 실행되는 경우
- 컴포넌트의 key props(특수한 props)가 변경되는 경우
- props가 변경되는 경우
- 부모 컴포넌트가 렌더링되는 경우
클래스형 및 함수형 컴포넌트의 차이는 해당 블로그를 참고해주세요
🌳 가상 돔이란
리액트는 렌더링이 발생하면 새로운 화면에 들어갈 내용들로 구성된 가상의 돔 트리를 생성합니다.
가상 돔은 실제 돔의 가벼운 복사본으로, 자바스크립트의 객체 형태로 메모리 상에만 존재합니다.
리액트는 항상 2개의 돔을 가지고 있습니다.
첫 번째 가상 돔은 변경 이전의 화면 구조를 담고 있고, 두 번째 가상 돔은 변경 이후의 화면 구조를 담고 있습니다.
따라서 2개의 가상 돔을 비교하여 변경된 부분을 찾아내고, 이것을 모아 = 집단화시켜 한번에 실제 돔에 반영합니다.
위에서 말한 것처럼 가상 돔은 실제 돔의 복사복이므로 실제 돔의 모든 요소와 속성을 공유합니다.
그러나 브라우저에 있는 문서에 직접적으로 접근하는 것은 불가능하기 때문에 화면에 보여지는 내용을 직접 수정할 수 없습니다.
🌳 가상 돔의 장점(사용 이유)
브라우저의 문서에 직접적으로 접근할 수 없음에도 불구하고 가상 돔을 사용하는 이유는 다음과 같습니다.
- 성능 최적화
- 브라우저에서 실제 돔을 조작하는 것은 매우 비용이 많이 드는 작업으로 빈번한 돔 조작은 성능 저하를 야기합니다.
- 따라서 가상 돔을 사용하여 변경 사항을 메모리에서 먼저 계산합니다.
- 계산 결과에서 변경된 부분만 실제 돔에 적용하므로, 불필요한 돔 조작을 최소화합니다.
- 재조정(Reconciliation)
- 새로운 가상 돔과 이전 가상 돔을 비교하여 어떤 부분이 변경되었는지 파악하고, 변경된 부분만 실제 돔에 반영합니다.
- 더 나아가 여러 상태를 한 번에 업데이트하는 'Batch Update'라는 방법을 사용하므로 매번 전체 돔 트리를 재렌더링하지 않아도 됩니다.
- 선언적 UI
- 리액트의 선언적 접근 방식은 개발자가 UI의 현재 상태를 선언하면, 리액트가 그 상태를 반영하도록 돕습니다.
- 상태(state)나 속성(props)이 변경되면 자동으로 UI를 업데이트합니다.
- 따라서 개발자는 UI 업데이트 로직을 직접 작성할 필요가 없습니다. 이는 코드 가독성을 높이고 유지보수를 쉽게 합니다.
- 그 외
- 리액트 Native와 같은 다른 플랫폼에서도 가상 돔을 사용할 수 있어, 리액트의 범용성을 높입니다.
- 가상 돔을 사용하면 애니메이션이나 전환이 더 부드럽게 실행되어, 사용자 경험을 향상시킵니다.
실제 문서 객체 모델(DOM)에 대한 내용은 이전 게시글을 참고해주세요.
[Javascript] 문서 객체 모델(DOM, Document Object Model)
읽어주셔서 감사합니다:)