[React] 리액트가 실제로 작동하는 방식

SuamKang·2023년 7월 19일
0

React

목록 보기
21/34
post-custom-banner

리액트는
사용자 인터페이스 구축을 위한 자바스크립트 라이브러리 라고 공식문서에서도 강조하고 있는 부분이다.

또한 리액트의 핵심은 컴포넌트라고 익히 알고 있다.

여기서 인터페이스를 구축하기 위해 컴포넌트를 사용하고 리액트 개발자들은 이 컴포넌트들을 통해 사용자 인터페이스를 효과적으로 구성해야하는 의무가 있다.



React vs ReactDOM

이러한 과정에서 중요한 개념이 바로 ReactDOM이다.
결론적으로, ReactDOM은 웹에 대한 인터페이스다.

단순하게 보기에 리액트는 브라우저와 전혀 관계가 없다.
리액트는 어떻게 컴포넌트를 다루는진 빠삭하게 알고 있지만 해당 컴포넌트에 어떤 html요소들이 포함되어 있는지 아님 아예 허구적인 요소가 있는지에 대해선 상관하지 않는다.

이는 ReactDOM이 고려하게 된다.

React는 컴포넌트와 상태객체를 관리하고 또한 다른 객체의 상태와 컴포넌트가 바뀌어야하는지를 확인하고 컴포넌트 변경 전후의 상태를 확인하는 라이브러리일 뿐이다.

그리고, 리액트는 변경된 내용과 어떤 화면이든 간에 화면에 표시되어야 할 정보들을 현재 사용중인 인터페이스에 전달한다.

예를 들면 ReactDOM과 같은것들을 말한다.

ReactDOM은 브라우저의 일부인 실제 DOM에 대한 작업을 하게 되고 따라서 사용자가 보고있는 화면에 무언가를 표시하는 역할 자체를 진행한다.


React는 컴포넌트에 전달하는 데이터인 props를 관리하여 컴포넌트 구성을 가능케 하고, 부모-자식 컴포넌트간의 통신을 연결해주는 아주 중요한 역할을 수행한다.

그리고, 컴포넌트 내부의 데이터인 state를 다루고 또한 컴포넌트 전체의 데이터인 context라는것도 다루고있다.
물론 더 많은 내장된 기능들이 있지만 위 키워드들이 핵심이다.

이들이 React를 통해 변경되면 React가 화면에 새로운것을 표시하는지 확인을 동시에 하게되는데

이 때, 화면에 무언가를 그리려 하면 React는 ReactDOM에 알려 새로운 화면과 컴포넌트를 출력 및 표시할 수 있게 해준다.

실제 DOM과 의 통신


이렇게 통신하는것을 지켜보면 React가 하는 역할은 가상DOM이라는 개념을 사용하고,
이 가상DOM은 앱이 마지막으로 만들어내는 컴포넌트 트리를 결정한다.

각각의 하위 트리를 지니고 있는 컴포넌트들은 JSX코드를 반환하는데 이 가상DOM이 컴포넌트 트리의 현재 모양과 업데이트 된 후 최종 모양을 정하게 된다.

React에서 상태 변화가 어떻게 ReactDOM에 전달되는가?


가령, 상태가 업데이트 되면 해당 정보는 ReactDOM으로 전달되어 갱신 전후의 상태 차이를 인식하고 React가 컴포넌트 트리를 통해 구성한 가상 스냅샷인 가상DOM과 일치하도록 실제DOM을 조작하게 해준다.

이 포인트에서 이 차이를 알아두어야 하는것은
state나 props,context등 컴포넌트에 변경이 발생하면 컴포넌트 함수가 재실행되어 컴포넌트를 재평가 하게 된다고 알고있다.
하지만 이 재평가하는 과정이 DOM을 다시 랜더링 하는것은 아니다는것을 명확히 알아둘 필요가 있다.

실제 DOM은 React가 구성한 컴포넌트의 이전 상태와 트리, 그리고 현재의 상태간의 차이점을 기반으로 변경이 필요할 때만 업데이트 된다.

즉, 실제 DOM은 필요한 경우에만 변경되어서 사실 통채로 DOM이 변경될때 주는 성능적인 측면에서 많은 이점을 가져다준다고 볼 수 있다. 이 작업은 메모리 안에서만 발생하기 때문에 현재상태를 가상으로 비교한다는건 간편하기도 하고 리소스도 적게 든다.

한 곳에서 작은 변경이면 직접조작해도 괜찮지만 소규모 변경이 발생한다면 그만큼 실제 DOM을 많이 사용하므로 페이지가 느려질 수 있다.


예시


그렇다면 위와 같이 어떻게 React가 가상DOM을 통해 2개의 스냅샷의 차이를 알아내는 방식이 되는건지 코드를 통해 살펴보자.

평가 방식

  • 자바스크립트 객체를 활용
  • 메모리 상에서 동작해서 훨씬 더 빠른 동작
  • 실제 DOM에 전부 적용되지 않아 연산 비용 최소화 가능
  • 랜더링 하는 과정을 추상화 했다고 볼수 있다.
<div class="content">
  <h1>Hi there!</h1>
</div>

위 시점이 마지막으로 컴포넌트 함수를 실행했던 시점이라고 봤을때
여기서 상태가 변경되어 새로운 문장이 추가되는 경우를 보면,

<div class="content">
  <h1>Hi there!</h1>
  <p>This is new one!</p>
</div>

이는 현재 평가 결과가 되는거고 이 경우에서 React는 이 두 스냅샷간의 차이를 파악하고 이를 ReactDOM에 보고하면 ReactDOM은 실제 DOM을 바꾸어 업데이트 한다.

아래는 위 코드에서 가상 DOM이 이전 DOM과 비교하는 과정이다.

const content =	{
	tagName: 'div',
    attributes: { class: "content"},
  	children: [
      {
      	tagName: "h1",
        textContent: "Hi there!",
      }
    ]
}
const content =	{
	tagName: 'div',
    attributes: { class: "content"},
  	children: [
      {
      	tagName: "h1",
        textContent: "Hi there!",
      },
      {
        tagName: "p",
        textContent: "This is new one!",
      }
    ]
}

이렇게 추가된 p요소부분만 새롭게 실제 DOM에 렌더링이 된다.
이렇게 하는것이 백그라운드에서 리액트가 작동하는 방식이다.

profile
마라토너같은 개발자가 되어보자
post-custom-banner

0개의 댓글