본문 바로가기
개발공부일지/React

React - Element 단위 이해하기

by Hynn1429 2023. 2. 23.
반응형

안녕하세요.

Hynn 입니다.

 

이번 포스팅에서는 React 에서 화면을 표시하는 가장 작은 단위라고 하는 Element 에 대해 알아보도록 하겠습니다.

Component 를 넘어가기 이전에, Element 를 가볍게 이해하고 넘어가는 페이지로 이해해주시면 좋겠습니다.

 

 

=========

=========

 

 

React 공식 문서에서도 Element 는 "React App 의 가장 작은 단위" 라고 정의하고 있습니다.

즉 React 에서 코드를 작성할 때, 코드의 가장 작은 구성요소가 Element 라는 의미를 갖습니다. 기존의 JavaScript 에서 사용한 "DOM" 객체의 Element 와는 달리 React Element 는 "plain Object" 라는 일반 객체로 구성이 되어 있습니다.

 

이 두가지의 차이점을 세부적으로 본다면, 아래와 같은 특징과 차이가 존재합니다.

 

  DOM (Document Object Model) React 
특징 1. Browser 의 JavaScript API 에서 제공하는 Native Object 

2. HTML/XML 문서의 요소를 나타냄
1. Component 의 설명을 나타내는 객체(Object)

2. Component 유형, 속성 및 자식의 대한 정보를 보유하는 JavaScript 객체
차이점 1. 가변적인 특징을 가지고 속성을 변경할 수 있음
2. 브라우저의 구현에 결합되어 있어, 브라우저 제한사항을 따름
1. 속성을 변경할 수 없음 
2. 플랫폼에 종속되지 않아, 환경에 제약받지 않음

위 차이를 활용하여 React Element 는 기존의 DOM 에 비해 조합이나, 재사용이 간편하며, 이러한 작은 조각단위의 모음을 통해 복잡한 사용자 인터페이스를 구축하기 보다 용이하게 작성이 가능합니다. 

 

이를 위해 React 에서는 항상 HTML 을 작성할때 , 아래의 기본적인 작성이 되어야 합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
</body>
</html>

바로 "<div id="root"></div>" 입니다.

이 안에 들어가는 모든 Element 를 바로 React DOM 에서 관리하기 때문에, 이를 "root DOM node" 라고 명칭합니다.

즉, React 에서는 이 "root" 노드 안에서 구현이 됩니다. 

 

이전에 예제에서 등장한 코드를 이해하기 위해서 예제를 사용하자면, 아래와 같이 작성이 되는 것이 필요합니다.

const root = ReactDOM.createRoot(document.getElementById("root"))
root.render()

React Element 를 render 하기 위해서는 먼저 ReactDOM.createRoot method 를 사용하여, "root DOM node" 를 선택해야 합니다.

그리고 난 뒤 이 root 내에 render 를 해야 합니다. 

 

 

위에서 설명했듯, React 의 객체는 속성을 변경할 수 없는 "불변객체" 입니다. 즉, Element 를 생성한 이후에는 생성한 Element 의 자식(Chlidren) 이나 속성(Attribute) 를 변경할 수 없습니다. 즉, render 가 된 시점에서는 랜더된 시점의 UI 를 보여줍니다. 

 

위 내용을 바탕으로 이해한다면, 결국 UI를 업데이트 하기 위해서는 매 프레임, 시점마다 새로운 Element 를 생성한 뒤, 이를 "root.render()" method 를 사용하여 전달해야 합니다.

이를 위해서 하나의 예시를 작성해보도록 하겠습니다. 

 

 

React 와 기존의 DOM 을 이용한 차이점을 간단한 코드로 구현을 하여 예시를 작성해보도록 하겠습니다.

 

1) DOM 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript">
        const Clock = () => {
            const div= document.createElement("div")
            const h1 = document.createElement("h1")
            const h2 = document.createElement("h2")

            const txt = "Hynn Tistory Blog"
            let time = `It is ${new Date().toLocaleTimeString()}`

            h1.innerHTML = txt
            h2.innerHTML = time

            div.append(h1)
            div.append(h2)

            document.querySelector("#root").innerHTML = div.innerHTML
        }
        setInterval(Clock, 1000)
    </script>
</body>
</html>

 

2) React 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
    const Tick = () => {
        return (
            <div>
                <h1>Hynn Tistory Blog</h1>
                <h2>It is {new Date().toLocaleTimeString()}</h2>
            </div>
            )
        }

        const root = ReactDOM.createRoot(document.getElementById("root"));
        root.render(<Tick />)
        setInterval(() => root.render(<Tick />), 1000)
    </script>
</body>
</html>

위 코드를 사용하여 시계를 구현할 때, 실제 요소가 변하는 환경은 아래와 같이 변합니다.

실제 결과물 영상을 살펴보겠습니다.

React 는 시간을 표시하는 요소만 초마다 업데이트가 이루어집니다.

하지만 DOM 을 이용해 작성한 코드는 코드 전체가 매 초마다 업데이트 되는 것을 살펴볼 수 있습니다.

 

물론 DOM 으로도 React 처럼 개별 요소만 업데이트 하는 코드를 작성할 수도 있겠지만, 이는 React 의 JSX 를 render 하는 것에 대한 차이를 보기 위해 작성되었습니다.

 

위 코드에서는 Tick 이라는 함수가 가 정의되고, return 값으로 JSX 요소가 반환됩니다. 이 요소에는 <div> 라는 부모 Element 내에 자식 Element 로 <h1>, <h2> Element 요소가 있고, <h2> 요소에는 동적 컨텐츠가 포함되어 있습니다. 

코드적으로는 React 는 최초에 "root.render(<Tick />)" 을 랜더링 한 뒤, setInterval 을 사용하여 매 초마다 다시 랜더하도록 작성이 되어 있습니다.

 

하지만 React 에서는 이를 효과적으로 처리하는 알고리즘이 포함되어 있습니다. 즉 코드상으로는 매 초마다 "setInterval" 을 사용하여 전체 화면을 다시 root.render 를 전달하지만, ReactDOM 에서는 이를 업데이트 해야할 부분을 결정하고 해당하는 요소만을 업데이트하는 빠르고 효율적인 알고리즘이 적용되기 때문에, 더욱 효과적인 사용을 제공합니다.

 

즉 위의 예제에서는 최초에 "root.render" method 를 사용하여 화면을 랜더링 한 이후에 React 는 현재의 화면과, 새로운 랜더링 요청의 버전을 비교합니다. 그리고 변경된 부분만을 감지하여 부분만을 업데이트 하므로, 코드작성상으로는 전체 랜더링처럼 보이더라도, 전체 화면을 랜더링을 하지 않고, 실제 업데이트 해야할 부분만을 효율적으로 업데이트 하기 때문입니다.

 

이제 다음 포스팅에서는 실제 React 에서 가장 중요한 Component 에 대해서 다루어보도록 하겠습니다.

 

감사합니다.

 

반응형

댓글