[번역] 리액트는 브라우저 스크린에서 어떻게 컴포넌트를 렌더하는가?

버건디·2023년 2월 3일
0

리액트

목록 보기
50/58

한국어로 더 직접적인 의미 전달을 위한 의역이 존재합니다.

원글 링크

브라우저상에서 어떻게 리액트가 UI를 렌더하는지 알려주는 초보자들을 위한 가이드

리액트의 중요한 기능들중 하나는 컴포넌트이다.

컴포넌트들은 리액트 앱의 블록들로 구성되어 있으며, 재사용 될 수 있고 독립적으로 처리 될수 있는 별도의 부분들로 유저 인터페이스를 구분할 수 있다.

리액트 컴포넌트는 stateful 하거나 stateless 할 수 있다. 리액트 컴포넌트는 선택적 input을 받고 브라우저 상에서 렌더되는 리액트 요소를 반환한다.

이 게시글에서 이 주제에 대해 조금 이따가 더 깊게 들어가보자.

리액트와 리액트 DOM

브라우저상에서 리액트를 동작시키기 위해, 우리는 2가지의 라이브러리가 필요하다.

리액트와 리액트 돔이다.

리액트 라이브러리는 보여지는 view들을 만들어내는 역할을 하고, 리액트 DOM 라이브러리는 실제적으로 브라우저상에서 UI를 렌더하는 역할을 한다.

리액트는 "선언적 프로그래밍 접근법" 을 사용한다.

즉, 우리가 직접 DOM을 업데이트 하는것이 아니라, 리액트에게 UI가 어떻게 되어야 하는지 단지 알려준다.

그러면 리액트와 리액트 DOM이 DOM을 업데이트 하는것이다.

그렇다면 리액트 돔은 어디서 온것인가?

리액트 DOM은 리액트와 DOM이 서로 상호작용하도록 하는 자바스크립트 라이브러리이다.

리액트는 DOM 업데이트나 브라우저와는 아무 연관성이 없다.

리액트 DOM이 리액트와 DOM 사이에서 중재자 역할을 하는것이다.

우리가 브라우저 상에서 보여지게 하고 싶은 컴포넌트들을 리액트 라이브러리를 통해 만든 후에,

리액트 돔은 ReactDOM.render() 이라는 함수를 사용함으로써,

DOM을 업데이트해서 브라우저 상에서 컴포넌트들이 실제로 보여지게 되는 렌더링 과정을 담당한다.

JSX 그리고 리액트 요소들

우리는 리액트 UI가 함수형 컴포넌트와 클래스형 컴포넌트 두가지의 컴포넌트들로 나누어진다는 것을 알고 있다.

함수형 컴포넌트를 예로 들어보자.

const App = ()=>
{
    return <h1>Hello World!</h1>;
}

이 코드로부터, 우리는 컴포넌트가 UI를 반환할 것이라고 생각하겠지만, 이 코드들은 HTML 코드가 아니라 JSX 라고 불리는 코드이다.

JSX 는 너의 자바스크립트 코드에 HTML 모양을 추가하는 자바스크립트 확장버전이다.

아직 헷갈리는가? 한번 위의 코드로 어떠한 일이 벌어지는지 살펴보자.

const App = ()=>
{
    return <h1>Hello World!</h1>;
}

너가 바벨 웹사이트에 접속해서 이 코드를 바벨 트랜스파일러에 작성한다면 이러한 결과가 나올것이다.

const App = () => {
	return /*#__PURE__*/React.createElement("hi", null, "Hello World!");
};

이것은 JSX가 매우 특정한 자바스크립트 객체를 생성하기 위한 간단한 구문적 설탕(?) 이라는 것을 보여준다.

React.createElement란 무엇인가?

리액트 요소는 단순히 메모리 상에서 DOM 요소를 설명하는 자바스크립트 객체이다. 우리는 리액트의 createElement 메서드를 사용해서 리액트 요소를 만들 수 있다.

그래서 지금까지 우리가 컴포넌트를 만들었던것은, 우리가 UI가 브라우저상에서 어떻게 보여져야 하는지에 대한 정보를 가지고 있는 자바스크립트 객체를 만들고 있던 것이다.

하지만, 만약에 브라우저가 리액트 요소를 이해하지 못한다면, 컴포넌트는 어떻게 브라우저 상에서 렌더링 될까?

위에서 리액트DOM이 어디서 온것인지 얘기 했던것처럼, 리액트 DOM은 브라우저 상에서 리액트 요소를 렌더링 하는 중재자이다.

리액트 DOM은 'type' 속성에 따라서 노드들을 재귀적으로 생성하고 DOM을 업데이트한다.

가상 DOM과 Reconciliation(재조정)

리액트는 가상 DOM 이라고 불리는 진짜 DOM의 복사본을 유지하는데, 이 가상 DOM은 DOM의 가상 표현일 뿐이다.

진짜 DOM을 조작하는 것은 비용이 많이 들기 때문에, 이 가상 DOM이 리액트가 빠른 이유들 중 하나이다.

우리가 데이터를 추가하거나 변화를 만들때, 리액트는 새로운 가상 DOM을 만들고 그것을 전의 것과 비교한다.

이 비교 알고리즘은 diffing 이라고 불리는데, 만약에 변화가 있다면 그것들을 일괄로 처리해서 전체 DOM을 리페인팅 하는 과정 없이 최소한의 변화들로만 진짜 DOM을 업데이트 한다.

이 가상 DOM을 만드는 과정과 전의 가상 DOM과 변화를 비교해서 DOM을 업데이트 하는 과정을 Reconciliation(재조정)이라고 부른다.

렌더링 과정

리액트 렌더링 주기에는 두가지의 단계가 있다. 1. 렌더링 단계, 2. 커밋 단계

1. 렌더링 단계

렌더링에는 초기 렌더링과 재렌더링, 총 2가지의 타입이 있다.

초기 렌더링은 너가 너의 어플리케이션을 처음 시작했을때 일어난다.

리렌더링은 너의 state나 props들이 업데이트 될때 일어난다.

여기에 초기 렌더링의 흐름이 어떻게 되는지에 대한 설명이다.

  1. 컴포넌트들은 파싱되고, JSX는 React.createElement를 사용하는 리액트 요소들로 변환되어서 메모리에 저장된다.

  2. 가상 DOM은 리액트 요소들을 사용하면서 만들어지고 커밋 단계로 보내진다.

2. 커밋 단계

커밋 단계는 리액트가 실제적으로 DOM을 조작하고 변화를 만들어내는 단계이다.

리액트가 diffing 알고리즘을 사용하여 새로운 가상 DOM과 전에 있던 가상 DOM의 비교가 끝나면(초기 렌더링은 한개의 가상DOM만 존재한다), 리액트 DOM 라이브러리를 사용해서 실제 DOM에 변화를 적용시킨다.

어떻게 리렌더링이 작동하는가

리렌더링은 state가 업데이트 되거나 prop이 컴포넌트 안에서 변화 됐을때 발생한다.

state 변경을 발생시킨 컴포넌트가 플래그 컴포넌트로 지정되어서 리렌더링 되고, 그 플래그 컴포넌트 아래에 있는 모든 자식 컴포넌트들도 리렌더링 된다.

여기에 리렌더링의 흐름이 어떻게 되는지에 대한 설명이다.

  1. 플래그 컴포넌트에서 state 변경이 일어난다.

  2. 해당 컴포넌트와 자식 컴포넌트들은 파싱되고, JSX는 React.createElement를 사용하는 리액트 요소들로 변환되어서 메모리에 저장된다.

  3. 리액트 요소들을 사용하는 새로운 가상 DOM이 만들어지고, diffing 알고리즘을 통해 전의 가상 DOM과 비교한다.

  4. 변화들은 커밋 단계로 보내진다.

알아둬야할 점 : 너가 현재 state와 동일한 값으로 state를 업데이트 하는 경우,
리액트는 자식을 렌더링 하지 않거나 해당 hook을 실행 시키지 않는다.

리액트는 Object.is 비교 알고리즘을 사용하는데, state 변경은 불변해야 하기 때문이다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글