[REACT] UI 트리 이해하기

UI를 트리로 모델링하는 이유

HTML은 DOM 트리로, CSS는 CSSOM 트리로 표현되듯, React 역시 컴포넌트를 트리 형태로 관리합니다. 이는 부모 컴포넌트가 자식 컴포넌트를 포함하는 계층 구조를 형성하며, UI의 복잡성을 체계적으로 다룰 수 있게 합니다. 트리 구조는 React의 선언적 렌더링과 효율적인 업데이트 메커니즘의 기반이 됩니다.

렌더 트리

렌더 트리는 React 컴포넌트가 실제로 화면에 렌더링되는 방식을 보여주는 구조입니다. 각 컴포넌트는 트리의 노드로 나타나며, 부모-자식 관계를 통해 계층적으로 연결됩니다.

예제: 렌더 트리

// BlogApp.js
import React from 'react';
import Header from './Header';
import PostList from './PostList';
import Footer from './Footer';

export default function BlogApp() {
  return (
    <div className="blog-app">
      <Header title="나의 블로그" />
      <PostList />
      <Footer />
    </div>
  );
}

import React from 'react';

export default function Header({ title }) {
  return (
    <header style={{ backgroundColor: '#f5f5f5', padding: '10px' }}>
      <h1>{title}</h1>
    </header>
  );
}

// PostList.js
import React from 'react';
import PostItem from './PostItem';

export default function PostList() {
  const posts = [
    { id: 1, title: 'React 배우기', author: '김작가' },
    { id: 2, title: 'JSX 탐구', author: '이코더' },
  ];

  return (
    <section>
      <h2>최신 포스트</h2>
      {posts.map((post) => (
        <PostItem key={post.id} title={post.title} author={post.author} />
      ))}
    </section>
  );
}

// PostItem.js
import React from 'react';

export default function PostItem({ title, author }) {
  return (
    <article style={{ borderBottom: '1px solid #ddd', padding: '10px' }}>
      <h3>{title}</h3>
      <p>작성자: {author}</p>
    </article>
  );
}

// Footer.js
import React from 'react';

export default function Footer() {
  return (
    <footer style={{ marginTop: '20px', textAlign: 'center' }}>
      <p>© 2025 블로그</p>
    </footer>
  );
}

렌더 트리 구조

- 루트: BlogApp
  - 자식: Header
  - 자식: PostList
    - 자식: PostItem
  - 자식: Footer
  • 계층 구조: BlogApp은 최상위 노드이며, 하위 컴포넌트들을 포함합니다.
  • 동적 자식: PostList는 posts 배열에 따라 PostItem의 개수가 달라집니다.
  • 렌더링 경로: React는 이 트리를 따라 JSX를 DOM으로 변환합니다.

모듈 의존성 트리

React 애플리케이션은 여러 파일과 모듈로 나뉘며 이들 간의 관계는 import/export 구문을 통해 설정됩니다. 이 관계를 트리로 표현한 것이 모듈 의존성 트리입니다. 빌드 도구(예: Webpack, Vite)는 이 트리를 분석해 필요한 모듈만 번들에 포함시킵니다.

예제: 모듈 의존성 트리

// index.js (엔트리 포인트)
import React from 'react';
import ReactDOM from 'react-dom/client';
import BlogApp from './BlogApp';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<BlogApp />);

의존성 트리 구조

- 루트: index.js
  - 의존: react, react-dom/client, BlogApp
    -BlogApp 의존: Header, PostList, Footer
      -PostList 의존: PostItem
  • 번들링 최적화: 불필요한 모듈을 제외해 파일 크기를 줄입니다.
  • 모듈 관리: 복잡한 애플리케이션의 유지보수가 쉬워집니다.

렌더 트리와 의존성 트리 비교

  • 렌더 트리컴포넌트의 렌더링 구조를 나타내며, UI가 실제로 어떻게 구성되는지를 보여줍니다.
  • 의존성 트리모듈 간의 연결 관계를 나타내며, 어떤 파일들이 함께 묶여서 번들링되는지를 결정합니다.

트리 최적화

렌더 트리 최적화

  • 불필요한 중첩 컴포넌트를 줄여 트리 깊이를 최소화
  • React.memo로 자식 컴포넌트의 재렌더링 방지

의존성 트리 최적화

  • import로 큰 모듈을 지연 로드
    • const LazyComponent = React.lazy(() => import('./HeavyComponent'))