✨ 핵심 빌딩 블록?
컴포넌트는 리액트의 핵심 빌딩 블록 중 하나입니다.
리액트에서 개발할 모든 애플리케이션은 컴포넌트라는 조각으로 구성됩니다.
컴포넌트는 UI
구축 작업을 훨씬 쉽게 만들어주지만,
그렇다고 우리가 리액트 이전에 프론트엔드 개발 환경을 경험하지 못했기에
무엇이 불편했고 리액트와 같은 컴포넌트 기반의 UI
라이브러리가
어떤 편안함이 존재하는지 잘 와닿지 않는다.
컴포넌트란 리액트의 핵심 빌딩
UI
요소를 표현하는 최소한의 단위이며,
화면의 특정 부분이 어떻게 생길지 정하는 선언체 라고 합니다.
컴포넌트를 생성하고 보여지고자 하는 UI
요소를 컴포넌트 내부에서 JSX
를
통해 선언하면 이를 리액트가 화면에 그려주었습니다.
리액트 컴포넌트가 선언체라는 개념이 아주 중요합니다.
그 이유는 리액트의 컴포넌트기반 개발 이전에는 브라우저에서 동적으로
변하는 UI
를 표현하기 위해 직접 DOM
객체를 조작하는 명령형 프로그래밍 방식으로 구현했습니다.
그럼 기존 명령형 프로그래밍과 리액트 컴포넌트 선언적 프로그래밍은 무슨 차이일까요
명령형으로 작성된 코드의 경우 Hello, World! 를 출력하기 위해
컴퓨터가 수행하는 절차를 일일히 코드로 작성해야만 합니다.
// Hello, World! 화면에 출력하기
// 순수 javaScript 명령형 코드
const root = document.getElementById('root');
const header = document.createElement('h1');
const headerContent = document.createTextNode(
'Hello, World!'
);
header.appendChild(headerContent);
root.appendChild(header);
React
코드의 경우 내가 UI
를 선언하고 render
함수를 호출하면
React
가 알아서 절차를 수행해 화면에 출력해줍니다.
즉 화면에 어떻게 그려야할지는 React
내부에 잘 숨겨져 추상화되어 있습니다.
// React 코드 (선언적인)
const header = <h1>Hello World</h1>; // jsx
ReactDOM.render(header, document.getElementById('root'));
DOM
을 직접 조작하여 명령형 프로그래밍 방식으로 작성하던 코드가 나쁜 것은 아닙니다.
격리된 코드에서는 차라리 리액트와 같은 UI 라이브러리
를 사용하지 않고 만드는게
더 빠르고 전체적인 번들 사이즈 측면에서도 더 효율적인 방법일 수 있습니다.
그러나 더 복잡한 UI시스템
에서는 관리하기가 기하급수적으로 어려워집니다.
✨ 렌더링에 대해 조금 더 자세히 알아보기
리액트에서 렌더링이란, 컴포넌트가 현재 props
와 state
의 상태에 기초하여
UI
를 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미합니다.
렌더링을 쉽게 설명하자면
HTTP 통신
을 배울 때 주방장과 웨이터를 예시를 사용해 설명해보면...
컴포넌트를 주방에서 요리하는 주방장이라고 하면
리액트는 손님으로부터 주문받아 주방에 전달하고 요리를 서빙하는 웨이터로 가정합니다.
그리고 손님이 주문하고 주방장이 만드는 것이 요리가 아닌 UI
라고 표현한다면,
그럼 렌더링이 일어나는 프로세스의 순서는?
triggering - UI
를 주문하고 주방으로 전달하는 것rendering - 주방
에서 컴포넌트가 UI
를 만들고 준비하는 것DOM
에 커밋한다는 것은 commit - 리액트
가 준비된 UI
를 손님 테이블에 올려놓는 것리액트에서 렌더링이 발생하는 경우는?
state
)에 변경이 발생했을 때,state
가 변경되었을 때props
가 들어올 때리액트 앱이 실행되고 첫 렌더링이 일어나면 리액트는 컴포넌트의 루트에서
시작하여 아래쪽으로 쭉 훑으며 컴포넌트가 반환하는 JSX
결과물을 DOM
요소에 반영합니다.
첫 렌더링은 자동으로 일어난 것이였습니다.
리액트 앱이 실행되면 리액트는 전체 컴포넌트를 렌더링 하고,
결과물을 DOM
에 반영해 브라우저상에 부여합니다.
첫 렌더링을 끝난 이후에 추가로 렌더링을 트리거 하려면 상태를 변경해주면 됩니다.
저희는 지금까지 setState
함수만을 다뤘지만 몇 가지가 더 있습니다.
컴포넌트 상태에 변화가 생기면 리렌더링이 발생합니다.
이때 여러 상태가 변경됐다면 리액트는 이를 큐 자료구조에 넣어 순서를 관리합니다.
주방 예시를 다시 들어보면 리렌더링은 음식점 손님이 첫 주문 이후에 갈증이 생겨
추가로 음료를 주문하거나 처음 받은 음식이 마음에 들지 않아
새로운 메뉴를 주문하는 것과 같습니다.
새로운 UI주문(리렌더링)이 일어나면 리액트가 변경된 내용을 주방에 있는 요리사인
컴포넌트에 전달하고 컴포넌트는 새로운 변경된 주문을 토대로 새로운 요리(UI
)를 만듭니다.
새롭게 만들어진 요리(렌더링 결과)는 리액트에 의해 다시 손님 테이블에 올려집니다.
브라우저의 렌더링과 리액트의 렌더링 엄연히 다른 독립적인 프로세스입니다.
렌더링이 완료되고 React
가 DOM
을 업데이트한 후 브라우저는 화면을 그립니다.
이 프로세스를 "브라우저 렌더링"
이라고 하지만 혼동을 피하기 위해 "페인팅"
이라고 합니다.
이제 여기에 더해서 DOM
과 VirtualDOM
을 다시 복습하면서 자세히 알아보도록 하자.