이롭게 현명하게

[React] 리액트 엘리먼트 (Element) 본문

웹 개발/React

[React] 리액트 엘리먼트 (Element)

dev_y.h 2024. 1. 8. 18:13
728x90
반응형

 

※ 본 포스팅은 윈도우11 환경에서 인프런 강의를 수강하며 정리한 내용입니다.

 


 

목차

 

Element란?

React Element와 DOM Element

Element 렌더링 과정

 


 


[Element란?]

 

Element 뜻

 

Element : 어떤 물체를 구성하는 성분으로  요소, 성분이라는 뜻이 있다.

마찬가지로 리액트의 Element도 리액트 앱을 구성하는 요소를 의미한다.

 

리액트 공식 문서에서 Element는 리액트 앱의 가장 작은 빌딩 블록들이라고 한다.

리액트 공식문서에서의 Element

 

즉, 리액트 앱을 구성하는 가장 작은 블록들을 Element라고 부른다.

 

웹 개발을 해본 경험이 있다면 Element를 한 번쯤은 들어봤을 것이다.

Element는 원래 웹 사이트에 대한 모든 정보를 담고 있는 객체인 DOM에서 사용하는 용어이다.

그래서 Element라고 하면 DOM Element를 의미했다.

더보기

 

크롬 개발자 도구

 

크롬 브라우저에서 개발자도구(F12)에서 Element 탭 화면이다.

보이는 것처럼 탭 이름부터 Element로 되어있기 때문에 Element들을 모아 놓은 것임을 알 수 있다.

하지만 보이는 Element는 React Element가 아닌 DOM Element로 HTML 요소를 나타낸다.

실제로 화면에서 볼 수 있는 것이다.

 

 


[React  Element와 DOM Element]

 

DOM Element : 실제 브라우저 DOM에 존재하는 Element

React Element : 리액트 Virtual DOM에 존재하는 Element

리액트 Element와 DOM Element

 

 

실제 브라우저의 DOM에 존재하는 Element는 DOM Element가 되는 것이고 리액트의 virtual DOM에 존재하는 Element가 바로 React Element가 된다.

결국 React Element는 DOM Element의 가상 표현이라고 볼 수 있다.

DOM ElementReact Element에 비해 많은 정보를 담고 있 상대적으로 크고 무겁다.

Element는 화면에서 보이는 것을 기술한다.

Element가 기술한 내용을 토대로 실제 우리가 화면에서 보게 되는 DOM Element가 만들어진다.

 


 

이 코드는 JSX를 사용하여 작성된 코드다.

const element = <h1> Hello, World! </h1>

코드가 실행 될 때 대입 연산자의 오른쪽 부분은 리액트의 createElement 함수를 사용하여 Element를 생성하게 된다.

이렇게 생성된 것이 바로 React Element가 되는 것이다.

그리고 리액트는 이 Element를 이용해 실제 우리가 화면에서 보게 될 DOM Element를 생성한다.

 

< React Element의 형태>

React Element는 자바스크립트 객체 형태로 존재한다.

Element컴포넌트 유형과 속성 및 내부의 모든 자식에 대한 정보를 포함하고 있는 일반적인 자바스크립트 객체이다.

이 객체는 마음대로 변경할 수 없는 불변성을 가지고 있다.

즉, 한 번 생성되면 바꿀 수 없다.

 

이 코드는 버튼을 나타내기 위한 Element이다. 단순히 자바스크립트 객체임을 알 수 있다.

{
    type:'button',
    props:{
        className: 'bg-green',
        children:{
            type:'b',
            props:{
                children : 'Hello, Element!'
            }
        }
    }
}

 

타입에 HTML 태그 이름이 문자열로 들어가는 경우 Element는 해당 태그 이름을 가진 DOM 노드를 나타내고 props는 속성에 해당한다.

 Element가 실제로 렌더링이 된다면 아래와 같은 형태의 DOM Element가 될 것이다.

<button class='bg-green'>
    <b>
        Hello, Element!
    </b>
</button>

 


 

< createElement 함수>

자바스크립트 코드는 리액트의 컴포넌트 Element를 나타낸 것으로 일반적인 자바스크립트 객체이다.

React Element는 자바스크립트 객체 형태로 존재한다.

이 객체를 만드는 역할을 하는 것이 createElement 함수다.

Element의 타입이 HTML 태그 이름이 문자열로 들어가는 것이 아닌 경우 사용한다.

React.createElement(
	type,
    [props],
    [...children]
)

 

createElement 첫 번째 파라미터 type : HTML 태그 이름이 문자열로 들어가거나 또 다른 react 컴포넌트가 들어간다.

개발자 도구에서 보았던 HTML 태그가 된다.

여기에 HTML 태그가 아닌 리액트 컴포넌트를 넣으면 어떻게 될까?

모든 리액트 컴포넌트는 여러 개의 자식 컴포넌트를 포함할 수 있고 자식 컴포넌트를 모두 쭉 분해해 보면 결국 HTML 태그가 나온다.

createElement 두 번째 파라미터 props : 개발자 도구에서 HTML 태그가 있고 해당 태그에 여러 가지 속성이 들어가 있다.

클래스나 스타일 같은 것으로 이런 속성을 attribute라고 한다.

props는 attributes보다는 좀 더 상위에 있는 복잡한 개념이지만 Element의 속성이라고 생각하면 이해하기 쉽다.

createElement 세 번째 파라미터 children : 해당 Element의 자식 Element 들이 들어간다.

실제 개발자 도구의 그림에서는 하나의 HTML 태그 하위에 여러 개의 하위 태그가 나오는 것을 볼 수 있다.

이러한 HTML 태그들이 결국 자식 Element가 되는 것이다.

더보기

 

createElement 함수가 동작하는 과정

이 코드에는 button 컴포넌트와 ConfirmDialog 컴포넌트가 있다.

function Button(props) {
    return (
        <button class={`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의 type은 html 태그가 아닌 리액트 컴포넌트의 이름인 Button이다.

이 경우 리액트는 버튼 컴포넌트의 Element를 생성해 합친다.

그래서 최종적으로는 Element는 다음과 같은 모습이 된다.

{
    type:'div',
    props:{
        children:{
            {
                type:'p',
                props:{
                    children:'내용을 확인하셨으면 확인 버튼을 눌러주세요'
                }
            }, 
            {
                type:'button',
                props:{
                    className:'bg-green',
                    children:{
                        type:'b',
                        props:{
                            children:'확인'
                        }
                    }
                }
            }
        }
    }
}

이처럼 컴포넌트 렌더링을 위해서 모든 컴포넌트가 createElement 함수를 통해 Element로 변환된다.

리엑트 엘리먼트는 우리 눈에 실제로 보이는 것을 기술한다.

 

 


[Element 렌더링 과정]

React Element는 매우 중요한 특징으로 불변성을 가지고 있다.

즉, Element가 불변성을 가지고 있다는 것은 한 번 생성된 Element는 변하지 않는다.

Element 생성 후에는 children이나 attributes를 바꿀 수 없다.

React Element는 우리 눈에 보이는 것을 기술한다.

그런데 Element가 변할 수 없다면 화면 갱신이 안 된다.

Element 생성 후에는 children이나 attributes를 바꿀 수 없다.

즉 Element는 다양한 모습으로 존재할 수 있지만 한 번 생성된 다음에는 변경할 수 없다.

 

붕어빵 틀에 반죽을 넣고 기다리면 붕어빵이 구워져서 나온다.

붕어빵 틀에서 나온 붕어빵 속의 내용은 바꿀 수 없다.

 

Component와 Element도 마찬가지다.

component와 element의 관계

Component는 일종의 붕어빵 틀이다.

붕어빵이 구워져서 나오는 과정은 Element를 생성하는 것이고 완성된 붕어빵은 Element 생성이 끝났기 때문에 변경할 수 없다.

그렇다면 화면에 변경된 엘리먼트들을 보여주기 위해서는 기존의 Element를 변경하는 것이 아닌 새로운 Element를 만든다.

새로운 Element를 만들어 기존의 Element와 바꾸는 것이다.

리액트의 장점 중 하나로 빠른 렌더링 속도가 있다.

이를 위해서 내부적으로 Virtual DOM 이라는 것을 사용한다.

virtual DOM 개념도 :&nbsp;https://www.oreilly.com/library/view/learning-react-native/9781491929049/ch02.html

Virtual DOM은 변경된 부분을 계산, 컴퓨트 딥 하고 해당 부분만을 다시 렌더링한다.

 

Element는 불변성을 가지고 있다.

화면에 새로운 내용을 보여주기 위해서는 새로운 Element를 만들어 기존 Element가 연결되어 있는 부분에 바꿔서 달면 된다.

 

리액트를 사용해서 개발하다 보면 상태 관리와 더불어 화면이 얼마나 자주 갱신되는지가 성능에 큰 영향을 미치게 된다.

이 과정에서 Element가 새롭게 생성된다는 것을 알고 개발한다면 효율적으로 사용할 수 있다.

Element를 생성한 이후에 실제로 화면에 보여주기 위해서는 렌더링이라는 과정을 거쳐야 한다.

 

root 라는 아이디를 가진 div 태그다.

<div id='root'></div>

별 볼 일 없는 HTML로 보이지만 모든 리액트 앱에 필수적으로 들어가는 아주 중요한 코드이다.

div 태그 안에 React Element들이 렌더링 되며 이것을 root DOM node 라고 부른다.

이 div 태그 안에 있는 모든 것이 React DOM에 의해서 관리되기 때문이다.

오직 react만으로 만들어진 웹사이트들은 단 하나의 root DOM node를 가지게 된다.

반면 기존에 있던 웹사이트에 추가로 react를 연동하게 되면 여러 개의 분리된 수많은 root DOM node를 가질 수 있다.

Virtual DOM에서 가장 최상단에 있는 노드가 바로 Root DOM node이다.

Root DOM node

root div에 React Element를 렌더링 하기 위해 다음과 같은 코드를 사용한다.

const element = <h1> 리액트 공부 </h1>;
ReactDOM.render(element,document.getElementById('root'));

Element를 먼저 생성하고 생성된 Element를 root div에 렌더링하는 코드이다.

렌더링을 위해 ReactDOM에 render라는 함수를 사용한다.

render(리액트 Element , HTML Element ) 이때 HTML Element는 DOM Element에 렌더링하는 역할을 한다.

React Element와 DOM Element는 다른 개념이다.

React Element는 React의 Virtual DOM에 존재하는 것이고 DOM Element는 실제 브라우저의 DOM에 존재한다.

결국 React Element가 렌더링 되는 과정은 virtual DOM에서 실제 DOM으로 이동하는 과정이라고 할 수 있다.

 

<요약>

Element는 불변성의 성질을 가지고 있다.

Element는 한 번 생성되면 바꿀 수 없으므로 Element를 업데이트하기 위해서는 다시 생성해야 한다.

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

 

728x90
반응형
Comments