初學者也能懂!React children 全解析與實戰教學
更新日期: 2025 年 4 月 14 日
《React 元件基礎介紹》:
- React 的開發邏輯:為什麼現代前端要用元件?
- React 元件是什麼?畫面積木的基本單位
- 什麼是元件樹?理解元件的父子與巢狀結構
- 撰寫第一個 React 元件:函式型元件入門
- 如何規劃與拆分元件?從 UI 切割建立模組思維
- 元件之間如何傳資料?Props 教學入門
- 初學者也能懂!React children 全解析與實戰教學
- React 元件可以有自己的資料?state 基礎觀念與使用
- 什麼是 prop drilling?當資料傳遞變成麻煩
- Context API 是什麼?解決 prop drilling 的痛點
- 比 Context 更好用的選擇?認識第三方狀態管理工具
在閱讀本文前,建議先閱讀《JSX 基礎介紹》
在學習 React 的過程中,你可能看過這樣的寫法:
<MyComponent>Hello</MyComponent>
或是這樣的:
<MyComponent />
這兩者到底差在哪?為什麼有的元件可以包東西,有的卻是空的?
關鍵就在於 React 元件的一個特殊屬性:children
。
children
是 React 元件的內建 props,用來接收你在元件標籤中所夾帶的內容。
了解它,能幫助你靈活設計畫面結構、實作插槽(slot)功能,也能讀懂 UI Library(像是 Material UI、Chakra UI、Ant Design)裡的元件使用方式。
理解 children
的基本概念
什麼是 children
?React 中最神奇的隱藏 props
在 React 中,當你在一個元件標籤中「包住其他內容」,這些內容就會自動被當成該元件的 props.children
。
來看一個具體的例子:
<MyComponent>
Hello
</MyComponent>
你看到的是 HTML-like 的寫法,但在 React 背後,其實這段程式碼會被轉換成 JavaScript 語法,如下所示:
<MyComponent children="Hello" />
這代表:
MyComponent
這個元件會收到一個 props 物件- 其中的
children
欄位值是字串"Hello"
換句話說,「children
就是包在元件標籤內的所有內容」。不論是文字、JSX、甚至函式的回傳值,React 都會把它們統一當作 children
傳給元件。
再舉一個稍微複雜一點的例子:
<MyComponent>
<h1>標題</h1>
<p>這是一段段落。</p>
</MyComponent>
React 會把 <h1>
和 <p>
這兩個元素包成一個陣列,當作 children
傳給 MyComponent
。也就是:
<MyComponent children={[
React.createElement('h1', null, '標題'),
React.createElement('p', null, '這是一段段落。')
]} />
這也解釋了為什麼你在元件中,只要寫:
function MyComponent({ children }) {
return <div className="box">{children}</div>;
}
就可以自動渲染裡面包的所有內容。
為什麼常常看不到這種寫法?— 自閉合標籤的背後邏輯
你可能會疑惑:「可是我常看到的元件都長這樣啊?」
<MyComponent />
沒錯,這就是所謂的「自閉合寫法(self-closing tag)」,等同於:
<MyComponent></MyComponent>
它們的意思一樣,差別只在於沒有包任何內容,所以 React 自然就不會把 children
傳入。
也就是說,這兩段程式碼:
<MyComponent />
<MyComponent></MyComponent>
都會被轉換成這樣的 JavaScript:
<MyComponent children={undefined} />
也就是 props.children === undefined
。
那為什麼會這樣寫?
因為這種寫法的元件,本身就是獨立運作、不需要顯示內部內容的元件,例如:
<Logo />
:只顯示一張 Logo 圖<Button onClick={...} />
:按鈕已經內建樣式與功能,不需要額外內容<LoadingSpinner />
:純粹顯示動畫
這些元件不需要 children
,自然就不需要包住內容。
小結:有沒有 children
,看你怎麼使用元件
元件寫法 | children 傳入值 | 適用場景 |
---|---|---|
<MyComponent>Hello</MyComponent> | "Hello" | 顯示可變內容、自訂畫面區塊 |
<MyComponent><div /></MyComponent> | React Element | 插入整段自定畫面 |
<MyComponent /> | undefined | 不需要內部內容的元件 |
這些基礎邏輯搞懂之後,未來你在閱讀開源 UI 套件、開發可組合元件時,就能更輕鬆理解:
- 哪裡需要傳入
children
- 為什麼某些元件沒有
children
也能正常運作 - 怎麼設計自己的元件,讓它能接收並渲染內部內容
React children
的五大資料型別
React 為了讓元件更具彈性,設計了 children
這個特殊的 props。
而它的強大之處就在於:支援多種資料型別,你幾乎可以將任意內容放在 <MyComponent>...</MyComponent>
中,只要是 React 能理解的格式,它就能正確渲染。
以下我們來一一拆解 React 中 children
常見的五大資料型別與它們的行為。
JSX / React Element(React 元素)
💡 什麼是 React Element?
React Element 是由 JSX 所產生的一種 JavaScript 物件,它描述了一個畫面要長什麼樣子。
React 會根據這個描述來渲染實際的 DOM 元素。
🔍 範例:
<MyComponent>
<div>Hello</div>
</MyComponent>
這裡的 <div>Hello</div>
就是一個 JSX 寫法,它會被 React 編譯成 JavaScript:
React.createElement('div', null, 'Hello')
📌 小提醒:
- 所有你看到的
<div>...
、<h1>...
、或<CustomComponent>...
,本質上都是 React Element。 - 這是
children
中最常見的型別之一,因為你幾乎會在畫面中放很多區塊式的元素。
字串(string)或數字(number)
你可以直接將純文字或數字當作 children
放進元件中,React 會自動將它們顯示為文字節點。
🔍 範例:
<MyComponent>Hello</MyComponent>
<MyComponent>{123}</MyComponent>
✅ React 會如何處理?
"Hello"
會變成一段文字出現在畫面上。123
也會顯示成「123」這串數字,不需要任何額外處理。
這是實作「標題」、「文字內容」、「計數器數字」等靜態資料最直覺的方式。
📌 小提醒:
- 如果你放的是數字或字串,不需要用
<span>
或<p>
包起來也可以顯示。 - React 自動幫你完成文字節點的轉換,非常直觀好用!
陣列(Array)
React 支援將多個元素以陣列的方式一起當作 children
傳遞,React 會逐個渲染每個元素,這種寫法在「動態列表」中特別常見。
🔍 範例:
<MyComponent>
{[<li key="1">A</li>, <li key="2">B</li>]}
</MyComponent>
React 接收到的是一個包含兩個 <li>
元素的陣列,並會渲染為:
<li>A</li>
<li>B</li>
📌 小提醒:
- 元素陣列中 每一項都需要一個獨特的
key
屬性,否則 React 會發出警告。 - 這種語法非常常見於
.map()
的應用中,例如:
const fruits = ['蘋果', '香蕉', '芒果'];
<MyComponent>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</MyComponent>
空值型別:null
、false
、undefined
React 對這三個值有一個特別的處理方式:完全忽略它們,不會渲染任何東西,也不會報錯。
這樣的設計讓你可以非常簡單地實作條件渲染(Conditional Rendering)。
🔍 範例 1:直接放入空值
<MyComponent>{null}</MyComponent>
<MyComponent>{false}</MyComponent>
<MyComponent>{undefined}</MyComponent>
畫面上完全不會出現任何東西。
🔍 範例 2:搭配邏輯運算實作條件渲染
<MyComponent>
{isLogin && <p>歡迎回來</p>}
</MyComponent>
- 當
isLogin === true
時,會顯示<p>歡迎回來</p>
。 - 當
isLogin === false
時,children
等於false
,畫面不會顯示任何東西。
📌 小提醒:
- 這是一種「不需要額外
if
判斷」的渲染技巧,讓程式碼更簡潔。 - 但別忘了
0
是 falsy 值,放進去會被顯示出來!
函式或表達式的執行結果
只要你傳入的是一個 合法的 JavaScript 表達式,並且它的回傳值是 React 支援的型別,React 就能正常渲染它。
🔍 範例:
<MyComponent>
{getContent()}
</MyComponent>
如果 getContent()
回傳的是:
return <p>這是內容</p>;
React 就會正常渲染這個 <p>
元素。
這也代表你可以依照條件去封裝邏輯,例如:
function getContent() {
return isLogin ? <p>歡迎回來</p> : null;
}
📌 小提醒:
- 這種模式讓畫面渲染邏輯與 JSX 結構解耦合,易於維護與測試。
- 函式中只要回傳 React 支援的型別(JSX、字串、null 等),React 都能正確處理。
小整理:五種合法的 children
類型對照表
類型 | JSX 寫法 | React 行為 |
---|---|---|
React Element | <MyComponent><div>Hi</div></MyComponent> | 渲染 <div>Hi</div> |
字串 / 數字 | <MyComponent>Hello</MyComponent><MyComponent>{123}</MyComponent> | 顯示為文字 Hello 或 123 |
陣列(含 JSX) | <MyComponent>{[<li>1</li>, <li>2</li>]}</MyComponent> | 每個元素都被渲染 |
空值型別 | <MyComponent>{null}</MyComponent> | 畫面上不渲染任何內容 |
函式執行結果 | <MyComponent>{getJSX()}</MyComponent> | 顯示函式回傳的 JSX 或文字內容 |
實作與範例,掌握 children
的用途
在上一章中,我們學會了什麼是 children
,也知道它是 React 元件中專門用來接收「包在元件標籤內的內容」的特殊 props。
這一章,我們就要實際操作,帶你一步步理解 children
的應用方式、視覺輸出結果,以及它在元件設計中的重要角色。
📦 實際範例:用 children
傳入自訂內容
來看看一個非常簡單的元件定義:
function Box({ children }) {
return <div className="box">{children}</div>;
}
這個 Box
元件的功能非常單純:它就是在畫面上輸出一個帶有 class="box"
的 <div>
,而裡面的內容則是由 props.children
動態決定的。
也就是說,Box 元件的畫面內容,完全取決於你怎麼使用它。
使用方式一:單一文字
<Box>
Hello
</Box>
在這個例子中,我們將字串 "Hello"
作為 children
傳入 Box
。React 在渲染時,會把這段文字當成內容放進 <div>
中。
🖨️ 輸出結果:
<div class="box">Hello</div>
✅ 解說:
Hello
是一段純文字(primitive string),被自動放入Box
的<div>
中。- 這種方式常用於靜態標題、按鈕文字等情境,簡潔又直覺。
使用方式二:一整段 JSX
<Box>
<h1>標題</h1>
<p>這是內容</p>
</Box>
這次,我們不是傳文字,而是傳入一整段包含標題與段落的 JSX 元素。這些元素會一起成為 children
,被渲染在 Box
中。
🖨️ 輸出結果:
<div class="box">
<h1>標題</h1>
<p>這是內容</p>
</div>
✅ 解說:
children
的值會是一個 JSX 陣列,包含<h1>
和<p>
兩個 React Element。- React 會自動幫你把它們逐個渲染出來。
- 這種方式很適合用在版面排版元件(如 Card、Modal、Section 等)中。
這就是 children
的典型用途
透過 children
,我們可以讓元件不再只是「單一功能」的組件,而是可以包裝任意內容、靈活配置畫面結構的容器。
它讓我們能夠:
- 建立「共用樣式但內容不同」的元件模板
- 組合多個元件在一起,提升重複利用率
- 實作像插槽(slot)那樣的設計模式
延伸思考:為什麼不用 props 傳內容?
你可能會問:為什麼不直接傳一個 title
或 content
props 呢?
當然可以,但 children
提供了更自由、不受限制的結構性內容,不需要定義太多 props。
比較一下:
用 children
:
<Card>
<h1>我是標題</h1>
<p>我是描述</p>
</Card>
用 props:
<Card title="我是標題" content="我是描述" />
props
適合傳單一資料項目(文字、數值)children
適合傳一段複雜結構(多層 HTML、元件、邏輯渲染)
結語
理解 children
不只是為了寫畫面,更是為了寫出有彈性、可組合、可擴充的元件。這是從新手 React 工程師,邁向實戰高手的必經之路。