React JS

[React] 리액트 JSX 와 렌더링 구조

챎 님 2025. 3. 25. 12:13
더보기

이 포스트는 남현우 교수님의 소프트웨어 설계 수업을 듣고 작성하였습니다.

리액트 JSX 에 대해 간단히 알아 보며, 실습을 통해 코드를 작성해 보겠습니다.

JSX 는 자바스크립트 확장 문법입니다.

const element = <h1>Hello, world!</h1>;

 

위 예시 코드는 일반 자바스크립트 문법인 대입 연산자(=) 오른쪽에 HTML 코드가 나오며, 이와 같은 자바스크립트 코드와 HTML 코드가 함께 사용되는 형태입니다.

 

JSX 는 내부적으로 XML/HTML 코드를 자바스크립트로 변환합니다.

createElement 함수에 대해 간단히 설명해 보겠습니다.

이 함수는 React에서 요소를 생성하는 데 사용되는 기본 함수입니다. 이를 통해 JSX 문법을 사용하지 않고도 React 요소를 만들 수 있습니다.

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

기본 형태는 이렇게 볼 수 있습니다.

  • type: 생성할 요소의 타입입니다. 예를 들어, 'div', 'span' 또는 컴포넌트 이름 등을 사용할 수 있습니다.
  • props: 요소에 전달할 속성입니다. 객체 형태로 전달되며, 속성이 없는 경우 null로 설정할 수 있습니다. 예를 들어, class, style, src 및 onclick 등...
  • children: 요소의 자식 요소들입니다. 여러 개의 자식 요소를 전달할 수 있습니다.

그렇다면, JSX 를 우리가 써야 하는 이유가 무엇일까요?

여러 장점이 있지만 두 가지로 정리해 보겠습니다.

먼저, createElement 함수의 복잡한 파라미터 사용 없이 동일한 작업 수행이 가능하기 때문에 코드가 간결해집니다.

//JSX 사용
<div> Hello, {name}</div>

//JSX 사용 안 함
React.createElement('div', null, 'Hello, ${name}');

 

두 번째는 가독성 향상입니다. 코드에 대한 의미 분석이 빨라지겠지요.

즉, 버그 발견도 빠르게 진행이 될 것 입니다.

 

간단히 코드를 적어 보며, JSX 에 대해 이해해 보겠습니다.

import React from "react";

function Book(prop) {
  return (
    <div>
      <h1>{"이 책의 이름은 ${props.name} 입니다."}</h1>
      <h2>{"이 책은 총 ${props.numOfPage} 페이지로 이뤄져 있습니다."}</h2>
    </div>
  );
}

export default Book;

위 코드를 Book.jsx 에 적어 보겠습니다.

 

import React from "react";
import Book from "./Book";

function Library(props) {
  return (
    <div>
      <Book name="처음 만난 파이썬" numOfPage={300} />
      <Book name="처음 만난 AWS" numOfPage={400} />
      <Book name="처음 만난 리액트" numOfPage={500} />
    </div>
  );
}

export default Library;

Library 입니다.

그 후 인덱스를 Library 를 불러 올 수 있도록 수정해 줍니다.

컴포넌트의 구조는 이렇게 됩니다.

이렇게 JSX 를 사용하게 된다면, 직접 코드를 하나씩 길게 작성하지 않아도 위치에 맞추어 불러 올 수 있기에 코드를 짜기에도 편합니다.

 

# 리액트 렌더링 구조

이제는 앞에서 간단히 보았던 createElmen() 함수가 생성한 객체인 엘리먼트의 개념과 역할을 알아보며, 렌더링 과정을 확인해 보겠습니다.

먼저, 엘리먼트의 개념은 무엇일까요?

이는 요소, 성분이라는 의미이며, 앱을 구성하는 요소를 뜻합니다.

리액트 엘리먼트와 DOM 엘리먼트의 관계에 대해 알아 보겠습니다.

 

리액트 엘리먼트를 사용하여 UI를 설명하고, 이 엘리먼트를 기반으로 실제 DOM 엘리먼트를 생성합니다.

즉, 쉽게 설명하면 리액트 엘리먼트는 React에서 UI를 정의하는 "설계도"이고, DOM 엘리먼트는 실제 웹 페이지에 표시되는 "구현" 입니다.

 

간단히 엘리먼트의 특징이 무엇인지 설명해 보겠습니다.

가장 큰 것은 불변성입니다. 엘리먼트는 생성 후에 children 이나 attribut 를 수정할 수 없습니다.

예를 들어 보자면, 붕어빵 틀(컴포넌트) 에서 구워져서 나와 버린 붕어빵(엘리먼트) 의 속 내용은 바꿀 수 없는 것처럼 말입니다.

 

그렇다면 화면에 변경된 엘리먼트를 보여 주려면 어떻게 해야 할까요?

새로운 엘리먼트를 생성한 후 기존 엘리먼트와 바꿔치기를 하면 됩니다.

 

 

# Root Dom Node

root 라는 id 를 가진 div 태그에 모든 리액트 엘리먼트들이 렌더링되며, 리액트 DOM 에 의해 관리됩니다.

즉, 리액트만으로 만들어진 앱은 단 하나의 Root Dom Node 를 가지게 됩니다.

Root DOM node 의 렌더링은 어떻게 진행이 될까요?

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

이는 createRoot 로 설정된 Root DOM Node 에 render 함수를 사용하여 화면을 렌더링 합니다.

엘리먼트가 렌더링되는 과정은 virtual DOM 에서 실제 DOM 으로 이동하는 과정입니다.

 

렌더링된 엘리먼트를 업데이트 하는 것은 위에 설명한 것과 같은 방법으로 다시 생성하여 바꿔치기 방식으로 진행하면 됩니다.

 

마지막으로 간단히 시계 컴포넌트를 만들어 보며, 마무리하겠습니다.

초 단위로 동작하도록 개발할 것이기에 setlnterval() 함수를 사용해야 합니다.

시간 정보를 추출할 때는 new.Date().toLocaleTimeString() 의 내장 함수를 사용합니다.

import React from "react";

function Clock(prop) {
  return (
    <div>
      <h1>현재 시간: {new Date().toLocaleTimeString()}</h1>
    </div>
  );
}

export default Clock;

Clock.jsx 의 코드입니다.

 

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

import Clock from "./components/Clock";

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

setInterval(() => {
  root.render(
    <React.StrictMode>
      <Clock />
    </React.StrictMode>
  );
});

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

index.js 의 코드를 Clock 코드에 맞추어 수정해 준다면,

이렇게 시간 초 단위로 움직이게 됩니다.

'React JS' 카테고리의 다른 글

[React] 리액트는? - 특징과 장점  (0) 2025.01.15