리액트(React) JSX 및 렌더링 구조

post-thumbnail

JSX

자바스크립트 코드 안에서 HTML과 유사한 문법을 사용할 수 있게 해주는 문법 확장

  1. HTML처럼 보이지만 실제로는 자바스크립트
    const element = <h1>Hello, JSX!</h1>;
  2. JS 표현식 사용 가능
    const name = "React";
    const element = <h1>Hello, {name}!</h1>;
  3. class 대신 className 사용
    <div className="container">Hello</div>
  4. 태그는 반드시 닫힘 필수
    <img src="image.png" />  // 올바른 문법

JSX의 역할

  • JSX는 내부적으로 XML/HTML 코드를 자바스크립트로 변환
  • 코드가 간결해지고 생산성과 가독성이 향상

JSX를 사용한 코드

const element = <h1 className="title">Hello, JSX!</h1>;
ReactDOM.createRoot(document.getElementById("root")).render(element);

JSX를 사용하지 않은 코드 (Vanilla React)

const element = React.createElement("h1", { className: "title" }, "Hello, JSX!");
ReactDOM.createRoot(document.getElementById("root")).render(element);

React.createElement()는 JSX를 사용하지 않고 리액트 요소(React Element)를 생성하는 함수

// 문법 형식
React.createElement(type, props, ...children)
매개변수역할
type생성할 요소의 태그 이름 또는 컴포넌트 (예: "div", "h1", MyComponent)
props요소의 속성(Attributes) 또는 className, id, onClick 등의 이벤트 핸들러 포함
...children해당 요소의 자식 요소(여러 개 가능), (텍스트, 다른 React 요소 등)

중괄호를 이용한 변수 참조

const name = "React";
const element = <h1>Hello, {name}!</h1>;
ReactDOM.createRoot(document.getElementById("root")).render(element);

중괄호를 이용한 함수 호출

function getGreeting(name) {
  return `Hello, ${name}!`;
}

const element = <h1>{getGreeting("React")}</h1>;
ReactDOM.createRoot(document.getElementById("root")).render(element);

자식(children)을 정의하는 방법

const element = (
  <div>
    <h1>Hello!</h1>
    <p>Welcome to React.</p>
  </div>
);

장점 : 코드가 간결, 가독성 향상, 보안성 향상(Injection Attack 해킹 방법을 방어)

이렇게 React에서 JSX의 형식을 사용하는 법을 알아보았습니다.

Element

  • 요소, 성분이라는 뜻을 가지며, 리액트의 앱을 구성하는 요소를 의미

  • 리액트 앱을 구성하는 가장 작은 블록

리액트 엘리먼트 및 DOM 엘리먼트의 관계

  1. 리액트 엘리먼트(React Element)는 DOM 엘리먼트의 가상 표현입니다.
    리액트에서 UI를 기술하는 불변 객체(Immutable Object)로, 화면에 보이는 요소를 나타낸다.
    하지만 자체적으로 브라우저 화면에 렌더링되지 않으며, 단순한 설명(Description) 역할을 합니다.

  2. 리액트 엘리먼트는 화면에 보이는 것들을 기술합니다.
    JSX 또는 React.createElement()를 사용하여 생성할 수 있습니다.
    예시 JSX 코드 :

    const element = <h1>Hello, React!</h1>;
    // React.createElement("h1", null, "Hello, React!")와 동일한 역할

    하지만 이 엘리먼트 자체가 DOM에 추가되는 것은 아닙니다.
    React는 위 엘리먼트를 토대로 실제 DOM 엘리먼트를 생성합니다.(아직 실행 안함)

  1. ReactDOM.createRoot().render()를 사용하면 리액트 엘리먼트가 가상 DOM(Virtual DOM)에 저장,
    React는 이를 실제 DOM 엘리먼트로 변환하여 웹 브라우저에 렌더링합니다.

    const element = <h1>Hello, React!</h1>;
    ReactDOM.createRoot(document.getElementById("root")).render(element);
    

결론 : 엘리먼트를 Virtual DOM에 저장해둔 다음 ReactDOM.createRoot().render()를 사용하면 그것의 변화에 따라 렌더링.
추가 설명은 아래 참조.

렌더링(Rendering)은 리액트 컴포넌트가 UI를 생성하고 업데이트하는 과정을 의미합니다.

렌더링 과정

  1. 리액트 컴포넌트가 실행됨 → JSX를 반환
  2. 가상 DOM(Virtual DOM) 생성 → 기존 가상 DOM과 비교
  3. 변경된 부분만 실제 DOM에 반영(Reconciliation)
  4. 화면 업데이트 완료

리액트의 렌더링 과정은 다음과 같이 이루어집니다.

React Element - DOM Element

// React Element
// Button 컴포넌트 정의
function Button({ color, children }) {
  return <button style={{ color }}>{children}</button>;
}
{
  type: 'div',
  props: {
    children: [
      {
        type: 'p',
        props: {
          children: '나중에 확인하셨으면 열 버튼을 눌러주세요.'
        },
      },
      {
        type: Button, // 사용자 정의 컴포넌트
        props: {
          color: 'green',
          children: '확인'
        },
      },
    ]
  },
}
// 렌더링
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(element);
// DOM Element
<div>
  <p>나중에 확인하셨으면 열 버튼을 눌러주세요.</p>
  <Button color="green">확인</Button>
</div>

위 React Element에서 렌더링을 하게 된다면 아래 DOM Element처럼 렌더링 된다.
위 코드에서 type: Button부분이 button이라면 컴포넌트 정의 필요없다.
결론 : HTML자체가 가지고있는 태그를 type에 사용시에는 컴포넌트 정의 필요없다.

Element 특징

  • 불변성(immutable) – 변하지 않는 성질
  • 엘리먼트 생성 후에는 child이나 attribute를 바꿀 수 없다.

그럼 문제가 하나 생깁니다.
그렇다면 화면에 변경된 엘리먼트를 보여주려면 어떻게 해야 할까? 라는 문제입니다.
답은 새로운 엘리먼트를 생성한 후 기존 엘리먼트와 바꿔치기하는 것입니다.

Root DOM node

  • root라는 id를 가진 div 태그에 모든 리액트 엘리먼트들이 렌더링되며, 리액트 DOM에 의해 관리됨.
  • 리액트만으로 만들어진 앱은 단 하나의 Root DOM Node를 가짐
profile
The learning never stops. 😂

0개의 댓글