react elements
Elements의 정의
리액트의 엘리먼트는 리액트 앱을 구성하는 요소를 의미한다
리액트 공식 홈페이지에서는 Elements are the smallest building blocks of React apps 라고 정의한다
=> 리액트 앱을 구성하는 가장 작은 블록들
실제 브라우저의 DOM에 존재하는 엘리먼트는 DOM 엘리먼트가 되는 것이고 React의 Virtual DOM에 존재하는 엘리먼트가 React 엘리먼트가 되는 것이다
=> 결국 React 엘리먼트는 DOM 엘리먼트의 가상 표현이라고 볼 수 있다
(DOM 엘리먼트는 React 엘리먼트에 비해 많은 정보를 담고 있기 때문에 상대적으로 크고 무겁다!)
React Elements는 화면에서 보이는 것들을 기술한다
=> 엘리먼트가 기술한 내용을 토대로 실제 우리가 화면에서 보게 되는 DOM 엘리먼트가 만들어진다!
const element = <h1>Hello, world</h1>;
이 코드가 실행될 때 대입 연산자의 오른쪽 부분은 React의 createElement 함수를 사용하여 엘리먼트를 생성하게 됨
=> 리액트는 이 엘리먼트를 이용해서 실제 우리가 화면에서 보게 될 DOM 엘리먼트를 생성함
Elements의 생김새
리액트 Elements는 자바스크립트 객체 형태로 존재
=> 한번 생성되면 바꿀 수 없는 불변성!
{
type : 'button',
props: {
className: 'bg-green',
children: {
type: 'b',
props: {
children: 'Hello, element!'
}
}
}
}
위 코드처럼 타입에 html 태그 이름이 문자열로 들어가는 경우
엘리먼트는 해당 태그 이름을 가진 DOM 노드를 나타내고 props는 속성을 나타낸다
<button class='bg-green'>
<b>
Hello, element!
</b>
</button>
그리고 이 엘리먼트가 실제로 렌더링이 된다면 위와 같은 DOM 엘리먼트가 됨!
다시 한번 createElement() 를 살펴보자~
{
type : Button,
props : {
color : 'green',
children : 'Hello, element!'
}
}
react-element는 JavaScript 객체 형태로 존재하는데 이 객체를 만드는 역할을 하는게 createElement 함수이다
이 함수를 호출할 때 3가지 파라미터를 넣었는데
type 부분에는 HTML 태그 이름이 문자열로 들어가거나 또 다른 react 컴포넌트가 들어가게 되고
이것이 개발자 도구를 통해서 보는 HTML태그가 된다
모든 react 컴포넌트는 최종적으로는 HTML 태그를 사용하게 되어있다
props 부분은 간단하게 엘리먼트의 속성이라고 생각하고 넘어가자
(추후에 자세히 다룰 예정)
children은 해당 엘리먼트의 자식 엘리먼트들이 들어간다
function Button(props) {
return (
<button className={`bg-${props.color}`}>
<b>
{props.children}
</b>
</button>
)
}
function ConfirmDialog(props) {
return (
<div>
<p>내용을 확인하셨으면 확인 버튼을 눌러주세요.</p>
<Button color='green'>확인</Button>
</div>
)
}
여기에서 confirmDialog 컴포넌트의 엘리먼트의 모습은
{
type : 'div',
props : {
children : [
{
type : 'p'
props : {
children : '내용을 확인하셨으면 확인 버튼을 눌러주세요.'
}
},
{
type : Button,
props : {
color : 'green',
children : '확인'
}
}
]
}
}
여기서 첫 번째 children은 type이 HTML 태그 중 하나인 p 태그이기 때문에 곧바로 렌더링이 될 수 있는 상태지만
두번 째 children은 HTML 태그가 아니라 React 컴포넌트의 이름인 Button이기 때문에 이 경우 Button 컴포넌트의 엘리먼트를 생성해서 합치게 된다
{
type : 'div',
props : {
children : [
{
type : 'p'
props : {
children : '내용을 확인하셨으면 확인 버튼을 눌러주세요.'
}
},
{
type : 'button',
props : {
className : 'bg-green',
children : {
type : 'b',
props : {
children : '확인'
}
}
}
}
]
}
}
이처럼 컴포넌트 렌더링을 위해서 모든 컴포넌트가 CreateElement 함수를 통해 Element로 변환된다는걸 기억하자
react element는 실제로 우리 눈에 보이는걸 기술함!!
Elements의 특성
1. immutable (불변성)
한번 생성된 elements는 변하지 않는다
=> Elements 생성후에는 children이나 attributes를 바꿀 수 없음
그렇다면 화면에 변경된 엘리먼트들을 보여주기 위해서는?
=> 이런 경우에는 기존 엘리먼트를 변경하는 것이 아니라 새로운 엘리먼트를 만들면 된다
(새로운 엘리먼트를 만들어서 기존 엘리먼트와 바꿔치기 하는 원리)
리액트의 장점중 빠른 렌더링 속도가 있고 이를 위해 내부적으로 Virtual DOM을 사용한다고 했었는데
State Change -> Compute Diff -> Re-render 의 순서이다!
(이 과정을 통해 기존 엘리먼트가 연결되어 있는 부분에 새로운 엘리먼트를 바꿔서 달면 된다)
Elements 렌더링하기
<div id="root"></div>
Root DOM Node
=> 이 div 태그 안에 리액트 엘리먼트들이 렌더링 되며 이것을 Root DOM Node라고 한다!
(이 div 태그 안에 있는 모든 것이 React DOM에 의해서 관리되기 때문)
오직 react만으로 만들어진 모든 웹사이트들은 단 하나의 Root DOM Node를 가지게 된다
루트 div에 실제로 react elements를 렌더링하기 위해서는
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Library />
</React.StrictMode>
);
다음과 같은 코드를 사용하는데
=> 결국 React elements가 렌더링되는 과정은 Virtual DOM에서 실제 브라우저의 DOM으로 이동하는 과정이다
렌더링된 Elements를 업데이트하기
elements는 불변성을 가지고있기 때문에 한 번 생성되면 바꿀 수 없고 elements를 업데이트하기 위해서는
다시 생성해야함!
function tick() {
const element = (
<div>
<h1>안녕, 리액트!</h1>
<h2>현재 시간: {new Date().toLocaleTimeString()}</h2>
</div>
);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(element);
}
setInterval(tick, 1000);
위의 코드를 보면 내부적으로 tick함수가 호출될 때마다 기존 elements를 변경하는 것이 아니라 새로운 elements를 생성해서 바꿔치기 하는 것이다!
'Frontend' 카테고리의 다른 글
React State와 Hooks (2) | 2024.03.05 |
---|---|
React Components and Props (0) | 2024.03.03 |
JSX란? (1) | 2024.03.03 |
리액트의 장점과 단점 (0) | 2024.03.02 |