React Function Component 的生命週期:從 setState 到 DOM 更新的完整解析
在學習 React 的過程中,常常會遇到一個疑問:Function Component 沒有生命週期方法,那它的 setState、render phase、commit phase、React element 與 DOM element 之間到底是如何運作的呢?
這篇文章將帶你一步步釐清它們的關係。
生命週期的三大階段
不論是 Class Component 還是 Function Component,React 的更新流程都可以分成三個主要階段:
-
Mount(掛載):元件第一次被建立並插入 DOM。
-
Update(更新):state 或 props 改變,元件重新渲染。
-
Unmount(卸載):元件被移除,清理資源。
Function Component 雖然沒有傳統的生命週期方法,但可以透過 Hooks 來模擬這些行為。
React 的運作階段
React 的運作流程可以分成 兩個主要階段:
-
Render Phase(渲染階段)
-
React 會呼叫 Function Component,計算出 新的 React element tree。
-
這個階段是純計算,不會操作瀏覽器 DOM。
-
React 會比對舊的 virtual DOM 與新的 React element(也就是 Reconciliation)。
-
-
Commit Phase(提交階段)
-
React 把差異套用到真實的 DOM element。
-
這時候畫面才會真正更新。
-
同時執行
useEffect、useLayoutEffect等副作用。
-
👉 注意:
-
初次掛載(Mount) 也會經歷 render phase → commit phase。
-
後續更新(Update) 依然是 render phase → commit phase。
-
差別只是 初次會建立整棵 DOM,而更新只會修改有差異的部分。
React Element 與 DOM Element 的差別
-
React element:用來描述 UI 的 JavaScript 物件,就像藍圖。
const element = <div>Hello</div>;
// React 內部會轉換成:
{
type: "div",
props: { children: "Hello" }
} -
DOM element:瀏覽器真實的節點,例如
<div>Hello</div>。
👉 React element 是 blueprint(設計圖),DOM element 才是成品。
setState :觸發 re-render 的重要角色
當呼叫 setState(例如 setCount(count + 1))時,React 會啟動以下流程:
-
Render Phase
-
React 重新執行 Function Component,生成新的 React element tree。
-
React 進行 Virtual DOM diff,比對新舊節點差異。
-
-
Commit Phase
-
React 更新真實 DOM element。
-
畫面改變。
-
執行
useEffectcallback。
-
流程圖
-
第一次掛載(Mount)
-
React 呼叫 function component → 建立 React element tree(render phase)。
-
React 產生對應的 DOM element 並插入頁面(commit phase)。
-
執行
useEffect(() => {...}, [])。
-
-
setState 觸發更新
-
呼叫
setState→ 通知 React 有狀態改變。 -
React 進入 render phase:重新執行 function component,生成新的 React element。
-
React 比對舊的 virtual DOM 和新的 virtual DOM。
-
React 進入 commit phase:只更新必要的 DOM element。
-
執行對應的
useEffect(() => {...}, [state])。
-
-
卸載(Unmount)
-
React 移除 DOM element。
-
執行
useEffect的 cleanup(return function)
-
範例程式碼:完整流程觀察
import { useState, useEffect } from "react";
export default function LifeCycleDemo() {
const [count, setCount] = useState(0);
console.log("Render Phase:執行 function component,產生 React element");
// 掛載 (Mount) + 更新 (Update)
useEffect(() => {
console.log("Commit Phase:DOM 已更新或初次掛載完成");
return () => {
console.log("Unmount:執行 cleanup,元件即將移除");
};
}, [count]);
return (
<div>
<h2>React Function Component 生命週期 Demo</h2>
<p>目前計數:{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
實際流程說明
第一次掛載(Mount)
-
React 呼叫 function component → 建立 React element tree(Render Phase)。
-
React 產生對應的 DOM element 並插入頁面(Commit Phase)。
-
執行
useEffect(() => {...}, [])。
Console 輸出:
Render Phase:執行 function component,產生 React element
Commit Phase:DOM 已更新或初次掛載完成
setState 觸發更新(Update)
-
呼叫
setState→ 通知 React 有狀態改變。 -
React 進入 Render Phase:重新執行 function component,生成新的 React element。
-
React 比對舊的 Virtual DOM 和新的 Virtual DOM(Reconciliation)。
-
React 進入 Commit Phase:只更新必要的 DOM element。
-
執行對應的
useEffect(() => {...}, [state])。
Console 輸出:
Render Phase:執行 function component,產生 React element
Commit Phase:DOM 已更新或初次掛載完成
卸載(Unmount)
-
React 移除 DOM element。
-
執行
useEffect的 cleanup(return function)。
Console 輸出:
Unmount:執行 cleanup,元件即將移除
✅ 這個範例會完整呈現:
-
Mount(初次掛載 → render phase + commit phase)
-
Update(setState → render phase + commit phase)
-
Unmount(移除元件 → cleanup)
總結
-
setState:觸發 re-render。
-
Render Phase:計算 UI,產生新的 React element tree。
-
Commit Phase:套用差異,更新 DOM element,執行副作用。
-
React element:UI 的藍圖(Virtual DOM 節點)。
-
DOM element:瀏覽器真實的節點。
理解這個流程後,你就能更清楚掌握 React 的運作機制,並在效能優化與除錯時更有方向。