1 - 08, 09. 리액트의 리렌더링 알아보기

msg016·2022년 6월 18일
0

React lecture

목록 보기
6/8
패스트캠퍼스 '한 번에 끝내는 React의 모든 것' 수강 후 정리.

개요

문서의 내용이 바뀌어 화면을 다시 그리게 되는 경우, 바닐라 JS로 구성된 화면과 리액트로 구성된 화면의 차이는 일반적으로 다음과 같다.

바닐라 JS -> 변경으로 인해 엘리먼트를 다시 그림.
리액트 -> 변경된 부분만 다시 그림.

코드로 예시를 들자면 다음과 같다. 1초 간격으로 버튼 안의 숫자가 랜덤으로 변경되는 화면이 있다고 하자.

// vanilla JS
function randomButton(parent) {
  const $button = `
    <button>${Math.floor(Math.random() * (10 - 1) + 1)}</button>
  `;

  parent.innerHTML = $button;
}

const $root = document.getElementById("root");  
setInterval(() => randomButton($root), 1000);
// react
function randomButton(parent) {
  const $button = (
    <button>{Math.floor(Math.random() * (10 - 1) + 1)}</button>
  );

  ReactDOM.render($button, parent);
}

const $root = document.getElementById("root");
setInterval(() => {
  randomButton($root);
}, 1000);

두 코드는 동일하게 setInterval를 통해 1초마다 randomButton함수를 호출하여 매개변수로 받은 부모 엘리먼트(여기서는 $root)에 랜덤으로 생성된 숫자가 적힌 버튼을 그려준다.

코드가 작동하면 화면은 동일하게 동작하는 듯 하지만 실제로는 아니다. 바닐라 JS로 작성된 화면의 경우 <button> 자체를 새로 만들어 화면에 그리고 있지만, 리액트의 경우 버튼은 그대로고 안의 숫자만 변경된다. 이는 포커싱을 통해 해제 여부의 차이나 DOM 및 스타일 검사기 등을 통해 변경되는 부분을 확인해보면 알 수 있다.

그러다면 무조건 리액트를 사용하는 것이 유리한가?

개발에 있어 모든 것은 Trade-off로, 얻는 것이 있다면 잃는 것도 있다.
리액트가 DOM의 어떤 부분만 갱신해야하는지 알기 위해서는 이전의 버전과 새로운 버전을 비교하고 다른 부분을 찾을 수 있어야 한다. 관리해야 하는 것들이 늘어나고, 항상 좋은 결과만 낳을 수는 없을 것이다.

React의 렌더링

공식 문서에서 살펴 본 리액트 렌더링 과정의 전반적인 특징은 다음과 같다.

  1. React 엘리먼트는 불변 객체이다.
    엘리먼트를 한 번 생성한 이후에는 해당 엘리먼트의 속성이나 자식을 변경할 수 없다.
    화면을 업데이트하는 유일한 방법은 새로운 엘리먼트를 생성하여 렌더를 요청하는 것이다.

  2. React는 트리를 비교할 때, 두 엘리먼트의 루트 엘리먼트부터 비교한다.
    엘리먼트 타입이 다르다면, 이전의 트리는 파기하고 새로운 트리를 구축한다.
    타입이 같다면, 속성(props)을 비교하여 변경된 부분은 갱신하고 동일한 부분은 유지한다.

이 두 가지 지식을 가지고 위의 리액트 코드를 다시 살펴보자.

위 코드는 매 1초마다 새로운 button 엘리먼트를 생성하여 ReactDOM.render()를 통해 리액트에 렌더링을 요청하고 있다. 요청을 받은 리액트는 이전 구조와 비교를 통해 갱신 부분을 찾아낼 텐데, 여기서 엘리먼트의 타입은 button으로 동일하다. 달라지는 부분은 안의 숫자, 즉 child 속성으로, 리액트는 이 달라진 child 속성만을 갱신하여 바닐라JS와는 다르게 button 엘리먼트는 유지하고 안의 숫자만 변경하도록 하는 것이다.

그렇다면 리액트는 어떻게 이전 구조와 새로운 구조를 비교할까?

간단히 말하자면 리액트는 내부적으로 가상 돔(virtual DOM)을 관리한다. 실제 DOM과는 구분되어 객체로 유지되는 트리 형태 구조로 이전의 화면 내용을 담고 있는 가상 돔과 새로운 화면의 가상 돔을 비교 알고리즘을 통해 비교하여 차이를 알아내고 수정해야하는 부분만 실제 DOM에 반영하는 것이다.

profile
프론트엔드 개발자 지망생

0개의 댓글