본문 바로가기

react

[소플] ch4. 엘리먼트 렌더링

1. 엘리먼트의 정의 

 

- Elements are the smallest building blocks of React apps

- 앨리먼트는 리액트 앱의 가장 작은 빌딩 블록

- 실제 브라우저의 DOM에 존재하는 엘리먼트는 DOM 엘리먼트가 되는 것이고, 리액트의 Virtual DOM에 존재하는 엘리먼트가 바로 리액트 엘리먼트가 됨 

- 리액트 엘리먼트는 DOM 엘리먼트의 가상 표현 

- 리액트 엘리먼트는 화면에서 보이는 것을 기술 

 

 

2. 엘리먼트의 생김새 

 

- 리액트 엘리먼트는 자바스크립트 객체 형태로 존재

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

 

ex) Button을 나타내는 엘리먼트 

 - type에 HTML 태그 이름이 문자열로 들어가는 경우, 엘리먼트는 해당 태그 이름을 가진 DOM Node를 나타내고 props는 속성을 나타냄

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

- 이 엘리먼트가 실제로 렌더링이 된다면 아래와 같은 DOM 엘리먼트가 됨 

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

 

컴포넌트 엘리먼트 (Component Element)

- type에 HTML 태그가 아닌 리액트 컴포넌트의 이름이 들어감

{
    type:Button,
    props: {
    	color:'green',
        children:'Hello, element'
    }
}

 

- 이 자바스크립트 객체를 만드는 역할을 하는 것이 createElement() 함수 

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

 

ex) createElement() 함수 동작 과정

//Button 컴포넌트 
function Button(props) {
	return (
    	<button className={`bg-${props.color}`}>
        	<b>
            	{props.children}
            </b>
        </button>
    )
}

//confirmDialog 컴포넌트 
funciton 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은 리액트 컴포넌트 이름인 Button

 - 이 경우에 리액트는 Button 컴포넌트의 엘리먼트를 생성해 합치게 됨 

 

- 최종적인 엘리먼트 모습

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

- 컴포넌트 렌더링을 위해서 모든 컴포넌트가 createElement() 함수를 통해 엘리먼트로 변환

 

 

3. 엘리먼트의 특징

 

-  엘리먼트 생성 후에는 children이나 attributes를 바꿀 수 없음

- 엘리먼트는 다양한 모습으로 존재할 수 있지만 한 번 생성된 다음에는 변경이 불가능 

- 화면에 변경된 엘리먼트를 보여주기 위해서는 새로운 엘리먼트를 만들어서 기존 엘리먼트와 바꿔치기 하면 됨 

 

 

4. 엘리먼트 렌더링 

 

- 엘리먼트를 생성한 이후에 실제로 화면에 보여주기 위해서 렌더링 과정을 거쳐야 함

 

- root라는 id를 가진 <div> 태그 

<div id = "root"></div>

- 이 <div> 태그 안에 리액트 엘리먼트들이 렌더링 되며, 이것을 Root DOM node라고 부름 

- <div> 태그 안에 있는 모든 것이 리액트 DOM에 의해 관리됨 

- 오직 리액트만으로 만들어진 모든 웹사이트들은 단 하나의 Root DOM node를 가지게 됨 

 

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

- 엘리먼트를 하나 생성하고 생성된 엘리먼트를 root div에 렌더링

- 렌더링을 위해 ReactDOM의 render () 함수 사용 

- 첫 번째 파라미터인 리액트 엘리먼트를 두 번째 파라미터인 HTML 엘리먼트에 렌더링하는 역할 

- 리액트 엘리먼트가 렌더링되는 과정은 Virtual DOM에서 실제 DOM으로 이동하는 과정

 

 

5. 렌더링된 엘리먼트 업데이트하기 

 

- 엘리먼트는 한 번 생성되면 바꿀 수 없기 때문에 엘리먼트를 업데이트하기 위해서는 다시 생성해야함 

 

function tick() {
	const element = (
    	<div>
            <h1>안녕, 리액트! </h1>
            <h2>현재 시간 : {new Date().toLocaleTimeString()}</h2>
        </div>
    );
    
    ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

- tick() 함수는 현재 시간을 포함하고 있는 엘리먼트를 생성하여 root div에 렌더링하는 역할 

- 자바스크립트 함수 setInterval()을 사용해서 tick() 함수를 매초 호출

- 내부적으로 tick() 함수가 호출될 때 마다 기존 엘리먼트를 변경하는 것이 아니라 새로운 엘리먼트를 생성해서 바꿔치기 하는 것

 

 

 

6. 실습 - 시계 만들기 

 

Clock.jsx

import React from "react";

function Clock(props) {
    return (
        <div>
            <h1>안녕, 리액트!</h1>
            <h2>현재시간: {new Date().toLocaleTimeString()}</h2>
        </div>
    );
}

export default Clock;

- Clock 컴포넌트는 현재 시간을 출력하는 컴포넌트 

- 만든 컴포넌트를 실제 화면에 렌더링하기 위해서 index.js 파일 수정

 

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import Clock from './chapter_04/Clock';



setInterval (()=> {
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
  <React.StrictMode>
    <Clock />
  </React.StrictMode>
);
},1000);

- setInterval() 함수를 사용해서 1,000ms(1초)마다 새롭게 Clock 컴포넌트를 root div에 렌더링 하도록 함