什麼是元件樹?理解元件的父子與巢狀結構

更新日期: 2025 年 4 月 14 日

當我們使用 React 開發網頁應用程式時,畫面不再是寫在一大堆 HTML 裡,而是由一個個「元件(Component)」組成。

這些元件就像一塊塊的積木,互相嵌套、組合,形成我們最終看到的畫面。這樣的結構,我們稱之為 元件樹(Component Tree)

了解元件樹的概念,不只是讓你知道畫面是怎麼組合的,更重要的是,它幫助你理解資料怎麼在元件之間流動、元件如何彼此互動,是學會設計 React 應用程式的關鍵第一步。


元件樹是什麼?為什麼要有「樹」的概念?

在 React 中,我們不再像傳統 HTML 一樣直接寫死整個畫面,而是透過「元件(Component)」來把畫面切成許多可以重複使用的小單位。

這些元件之間彼此不是平行關係,而是具有「階層性」的組合關係——也就是誰包含誰、誰在誰裡面。

這種上下層次的結構,就像一棵「樹」,從根幹一路分出枝葉,最終長成完整的模樣。

這個概念,在 React 開發裡就叫做「元件樹(Component Tree)」。

為什麼叫「樹」?

「樹(Tree)」這個詞並不是比喻,而是一種實際存在於程式設計中的資料結構

在元件樹中:

  • 每一個元件就像一個節點(node)
  • 父元件是主幹,子元件是分支
  • 每個節點可以有自己的子節點(巢狀元件),但只有一個直接的父節點
  • 最頂層的元件稱為「根元件(Root Component)」,通常就是 App

透過這樣的結構,React 可以清楚地知道每個畫面元件是如何組合、互相依附的,也才能實現像是 資料由上而下流動、狀態集中管理、重新渲染控制 等核心功能。

graph TD
    App[App] --> Header[Header]
    App --> Content[Content]
    App --> Footer[Footer]
    
    Header --> Navbar[Navbar]
    Header --> SearchBar[SearchBar]
    
    Content --> Sidebar[Sidebar]
    Content --> MainContent[MainContent]
    
    MainContent --> ProductList[ProductList]
    ProductList --> ProductCard[ProductCard]
    
    ProductCard --> ProductImage[ProductImage]
    ProductCard --> ProductInfo[ProductInfo]
    ProductCard --> AddToCartButton[AddToCartButton]
    
    Footer --> FooterLinks[FooterLinks]
    Footer --> Copyright[Copyright]

實際範例:組裝一個基本畫面

假設你要組一個簡單的網頁畫面,包含三個區塊:上方的導覽列(Header)、中間的內容區(Main)、下方的頁尾(Footer),你可能會寫出這樣的 React 程式碼:

function App() {
  return (
    <div>
      <Header />
      <Main />
      <Footer />
    </div>
  );
}

在這段程式碼中:

  • App 是「根元件」,它包住整個畫面
  • 它底下的三個元件:HeaderMainFooter 就是它的子元件

而每個子元件裡,又可能有更細的元件,例如 Header 裡面有網站 Logo 和選單:

function Header() {
  return (
    <nav>
      <Logo />
      <NavMenu />
    </nav>
  );
}

這時整個元件階層會變成這樣:

App
├── Header
   ├── Logo
   └── NavMenu
├── Main
└── Footer

這樣的結構圖,就是元件樹的雛形。你可以想像它像是:

  • App 是樹的主幹
  • Header、Main、Footer 是主幹分出的第一層枝幹
  • Header 底下再分出 Logo 和 NavMenu,就像再往下長出的小枝條

父元件與子元件:誰包含誰?

在 React 的開發邏輯中,「父元件(Parent Component)」與「子元件(Child Component)」的關係,是組成畫面與管理資料的核心基礎。

理解這個階層關係,就像你在認識一棟房子裡每個房間之間的關聯一樣:誰負責整體、誰負責局部、誰又只是其中一小塊。

父元件(Parent Component):掌控整體的上層元件

父元件是指「直接包含其他元件的元件」,它負責組合與管理底下的子元件。父元件就像一個主控台,可以決定要顯示哪些子元件,並且把資料、參數(props)傳遞給它們。

範例:

function App() {
  return (
    <Header />
  );
}

這裡 App 就是 Header 的父元件,因為它在 JSX 裡明確地把 Header 包起來。

子元件(Child Component):由父元件使用的元件

子元件是「被其他元件包含的元件」,它的生命週期與功能範圍,通常由父元件決定。子元件負責處理自己那一小塊畫面內容,並依據父元件給的資料(props)顯示不同狀態。

範例:

function Header() {
  return (
    <nav>
      <Logo />
      <NavMenu />
    </nav>
  );
}

在這裡,LogoNavMenu 就是 Header 的子元件。Header 負責組裝它們,並可能決定要不要顯示、要傳什麼資料進去。

父子關係的特性

React 中的父子元件有幾個重要的結構與邏輯特徵,你一定要掌握:

1️⃣ 一個元件只能有「一個」直接的父元件

每個子元件只能出現在一個 JSX 結構中,所以它的父元件是明確唯一的。雖然同一個子元件可以重複被使用,但每次使用時它都有一個特定的父元件。

<App>
  <Header />  ← Header 的父元件是 App
</App>

2️⃣ 一個父元件可以擁有「多個」子元件

就像 App 同時包含 HeaderMainFooter,這是最常見的使用方式。父元件可以自由組合需要的子元件,建立畫面。

function App() {
  return (
    <div>
      <Header />
      <Main />
      <Footer />
    </div>
  );
}

巢狀結構(Nested Components):React 的基本組裝方式

在 React 中,我們的畫面不是一口氣寫完的,而是「層層包起來」的。

這種層層包裝、逐層細分的方式,就叫做 巢狀結構(Nested Components)。也就是說,一個元件的內容裡面,還可以放別的元件,而這些被包進來的元件,也可以再包其他元件,形成像俄羅斯娃娃一樣一層包一層的結構。

這種結構不只是語法上的寫法,更是 React 建構使用者介面的核心邏輯。

巢狀元件的比喻:用元件「蓋房子」

你可以把整個畫面想像成一間房子(App),裡面有很多空間和裝潢。巢狀結構就像這樣的空間設計:

  • App 就像是整間房子的藍圖
    它決定要蓋哪些區域、分配哪些空間。
  • 房子裡有三個主要房間:Header、Main、Footer
    每個房間都有特定功能——導覽列、內容區與頁尾。
  • 每個房間裡有自己的家具與裝飾
    例如 Header 裡面有 LogoNavMenuMain 裡面有 ArticleSidebar

這種從外到內、一層包一層的方式,就是 巢狀元件 的具體呈現。

範例:使用巢狀結構組合畫面

來看一段簡單的 React 程式碼,說明巢狀結構如何讓畫面更有組織性:

function App() {
  return (
    <div>
      <Header />
      <Main>
        <Article />
        <Sidebar />
      </Main>
      <Footer />
    </div>
  );
}

這段程式碼中:

  • App 是整體畫面的根元件(Root Component)
  • 它直接包含了三個子元件:HeaderMainFooter
  • Main 又是 App 的子元件之一,同時它自己也包含了 ArticleSidebar,這就形成了巢狀結構

這段元件關係若畫成樹狀圖,就像這樣:

App
├── Header
├── Main
   ├── Article
   └── Sidebar
└── Footer

每一層的元件都只專注於自己的「責任區」,再透過巢狀結構將整體組合起來,這樣就能讓程式碼更乾淨、模組化、可維護。

巢狀結構的好處

巢狀元件不只是「包起來」而已,它帶來的效益非常多:

✅ 1. 專責化(Separation of Concerns)

每個元件只負責自己要處理的那一塊,讓邏輯與畫面都更清楚。

✅ 2. 重用性高(Reusability)

如果 Sidebar 是一個通用的元件,可以在多個畫面中巢狀使用,避免重複寫相同的程式碼。

✅ 3. 易於維護與測試(Maintainability & Testability)

小元件單元容易除錯、測試,也比較不容易牽一髮動全身。

✅ 4. 彈性組合(Flexible Composition)

可以根據需求自由組合元件內容,畫面變動時不用整塊重寫。

小結:巢狀結構是組織畫面的關鍵設計模式

巢狀元件的設計思維,是 React 最基本也最強大的特點之一。你只需要記住:

  • 元件可以像積木一樣層層堆疊
  • 每個元件都可以包含其他元件
  • 每一層都能拆成獨立模組,讓整體架構更清楚

資料怎麼流動?元件樹與資料流的關係

在 React 中,元件之間不只是巢狀結構,也存在著明確的「資料流動」邏輯。

這個資料流的設計,決定了我們如何在元件之間傳遞資訊、控制畫面、觸發互動。

理解這一點,就能幫助你寫出更有組織、好維護的程式碼。

React 採用的是「單向資料流」(One-way Data Flow)

React 最核心的資料傳遞原則就是:

👉 資料只能由父元件傳遞給子元件,不能反向傳遞。

這表示:

  • 父元件 可以把資料 傳給子元件
  • 子元件 不能主動去「改變」父元件的資料
  • 如果子元件想影響父元件,只能 請求父元件幫忙(透過函式)

這樣的設計,讓整個資料流動方向非常清楚、有預測性,不會像「雙向綁定」一樣容易搞混更新邏輯。

元件樹中的資料流方向:由上而下

在元件樹中,資料的傳遞就像水往下流,從上層的父元件一路傳到下層的子元件。你可以把它想成這樣的流程:

App (父)
  └── Header (子)
        └── Logo (孫子)

假設 App 裡面有一段資料 siteName

function App() {
  const siteName = "My React Blog";
  return <Header title={siteName} />;
}

AppsiteName 當作 title 傳給 Header,然後 Header 又可以把它再往下傳:

function Header({ title }) {
  return (
    <header>
      <Logo name={title} />
    </header>
  );
}

function Logo({ name }) {
  return <h1>{name}</h1>;
}

這整段資料流動方向是這樣:

App  Header  Logo

資料從最上層傳到最下層,每層都被動接收資料,而不是主動向上索取,這就是單向資料流的精神。


子元件不能直接修改父元件資料

因為資料是由父元件控制的,所以子元件即使拿到了資料(props),也不能直接改它。你可以想像 props 是「唯讀的資料傳單」,只能看,不能改。

這樣的限制,其實是一種保護設計

  • 防止資料在多個元件中同時被修改、造成難以追蹤的錯誤
  • 保持元件之間的職責清楚,誰擁有資料,誰就負責更新

子元件如何回報父元件?透過「callback function」

如果子元件想要「通知父元件發生了什麼事」,可以透過 props 傳遞一個函式 給子元件,讓子元件在需要時呼叫它。

📦 範例:子元件觸發事件、父元件處理資料

function Parent() {
  const [message, setMessage] = useState("Hello");

  const updateMessage = () => {
    setMessage("Child clicked!");
  };

  return <Child onClick={updateMessage} text={message} />;
}

function Child({ text, onClick }) {
  return (
    <div>
      <p>{text}</p>
      <button onClick={onClick}>Change Message</button>
    </div>
  );
}

這段邏輯的意思是:

  • Parent 是資料的持有者與控制者,擁有 message 狀態
  • 它把 message 傳給 Child,讓 Child 顯示
  • 同時也把 updateMessage 這個函式傳給 Child
  • Child 的按鈕被按下,它會呼叫 onClick(),請求父元件去改變資料

這種模式就是 React 常見的「父控制、子觸發」結構。

小結:資料流是 React 元件溝通的基礎

你可以這樣記住 React 的資料流邏輯:

關係行為說明
父 → 子用 props 傳資料
子 → 父用 props 傳進來的函式 觸發
子 不能改 父props 是唯讀的
父 擁有資料權所有資料與狀態由父元件主導

這樣的規則,讓整個應用程式的資料流動有方向、可預測、好除錯,是 React 的設計哲學之一。


結語:從「畫面」到「邏輯」的第一步

React 不只是幫你畫畫面,而是幫助你用程式思維管理畫面背後的邏輯。而元件樹就是這個思維的第一步。

當你能清楚劃分父子元件、理解巢狀關係與資料流動,你就邁出了成為 React 開發者的重要一大步。

接下來,就可以開始學習怎麼撰寫自己的元件,並善用 props 和 state 讓畫面動起來!

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *