React 元件生命週期一次搞懂:從誕生到離開,它經歷了哪些階段?
更新日期: 2025 年 4 月 14 日
在你踏入 Hook 的世界之前,有一個觀念非常關鍵 —— 你要先了解 React 元件是怎麼「活著」的。
React 並不是畫面 render 一次就結束,它背後其實運行著一套「生命週期」的機制,幫助我們在適當的時機做適當的事情。
這篇文章,我們不談 Hook、不談函式型元件,只專注在 class 元件的生命週期(lifecycle)概念,幫助你建立 Hook 之前該有的背景知識。
🔰 前言:React 不是一次畫完就沒事了
很多剛接觸 React 的初學者,對元件的理解可能是這樣的:
「我寫了一個元件,它顯示出來了,這樣就完成了吧?」
乍看之下沒錯,但這樣的想法其實忽略了 React 的真正強大之處 —— 它是一個會隨著資料改變而自動更新的 UI 系統,而這也意味著:
👉 元件並不是靜態的 HTML,而是有「生命週期」的動態單位!
🎯 React 元件是一個「有生命」的存在
你可以把每個元件想像成一個在網頁上「出生、成長、最後消失」的小角色。
在這個過程中,你可能會想讓它做一些事情,例如:
- 在元件「剛出現」的時候,向伺服器發送 API 請求,載入資料
- 在元件「被更新」的時候,根據新的資料重新執行某些動畫
- 在元件「即將消失」的時候,清除事件監聽器或中止計時器,避免記憶體外洩
這些事情,像是抓資料、加入事件監聽、開啟動畫效果,都不是隨便想寫在哪就能寫的。
舉個例子:
React 每個元件都會有一個叫做 render()
的函式,負責「描述畫面要長什麼樣」。
你可以把它想成畫畫用的藍圖:它只是負責告訴 React 要畫什麼,不能真的在這裡「做事」。
所以如果你把像是抓資料、操作 DOM、設定計時器這些「動作」寫在 render()
裡,React 可能會報錯,或造成畫面反覆更新,甚至整個卡住。
✅ 簡單來說:
render()
是畫畫用的地方,不是做事的地方。
那我們該把這些「該做的事」放在哪裡呢?
這時候就需要一個幫你規劃好「什麼時候該做什麼」的流程,讓元件在正確的時間點完成正確的事情。
這個流程就是我們接下來要介紹的重點:
🌀 元件生命週期(Component Lifecycle)
它就像劇本一樣,把一個元件從「出生 → 使用 → 結束」的每一個階段都規劃清楚,讓你知道:
- 什麼時候可以初始化資料?
- 什麼時候適合啟動動畫?
- 什麼時候要清除資源、收拾善後?
React 元件生命週期是什麼?
當你在畫面上放入一個 React 元件,它其實就像是一個有「生命」的個體一樣,會經歷:
- 誕生(Mounting)
- 成長與改變(Updating)
- 死亡(Unmounting)
你可以想像這個元件就像一個演員,從走上舞台、演出過程中根據劇情改變表現,最後退場。整個過程就叫做「元件的生命週期(Component Lifecycle)」。
這是 React 幫你安排好的一套流程,讓你可以在對的時機點,做對的事。
Mounting(掛載)
當元件第一次出現在畫面上,會經歷這個階段。
你可以在這時:
- 初始化資料
- 抓 API 載入內容
- 加入 DOM 事件監聽
- 啟動動畫或計時器
簡單來說,這是元件第一次「出生」的時間點。
Updating(更新)
當元件收到新的 props
,或內部 state
改變時,就會重新渲染畫面。這就是更新階段。
你可以在這時:
- 根據新資料更新畫面
- 比較新舊值做條件處理(例如觸發動畫)
- 做效能優化(例如決定要不要真的更新畫面)
這階段發生的頻率可能很高,因為 React 是個「會根據資料自動更新畫面」的框架。
Unmounting(卸載)
當元件要從畫面上消失(例如被條件隱藏或頁面切換)時,會進入卸載階段。
你可以在這時:
- 移除計時器
- 取消事件監聽
- 中止未完成的 API 請求
這階段最重要的工作是「收尾」,避免記憶體洩漏或不必要的運算繼續存在。
React 元件的三階段流程總覽
理解概念後,我們來看一下 class 元件在這三個階段中,實際會呼叫哪些生命週期方法(lifecycle methods):
✅ 小提醒:這些生命週期方法只在 class 元件中存在。你之後會學到,在函式元件中要靠 Hook 來實作這些能力。
生命週期是 React 的「舞台流程表」
你可以把這整個流程想成一場演出:
階段 | 比喻 | 對應方法 | 你可以做的事 |
---|---|---|---|
登場 | 登台開場 | constructor + componentDidMount | 初始化 + 抓資料 |
表演中 | 劇情發展、換裝 | render + componentDidUpdate | 更新畫面、觸發效果 |
退場 | 下台收工 | componentWillUnmount | 停止計時器、清除資源 |
這套機制讓你的元件不只是畫面,而是一個有節奏、有邏輯的「行為單位」。
接下來,我們會逐一拆解這些階段可以做什麼,幫你掌握元件的完整生命流程。
各階段能做什麼?你該怎麼用?
在 React 的三大生命週期階段中,每一階段都有對應的函式(lifecycle methods),幫助你在「正確的時間點」執行「該做的事」。
這段會帶你逐步拆解每個階段可以使用的函式,以及適合處理的邏輯。
掛載階段(Mounting)
這是元件第一次被放進畫面(DOM)中的階段,常見函式如下:
函式 | 說明 |
---|---|
constructor() | 元件剛被建立,可以用來設定初始 state 或綁定方法 |
render() | 描述畫面內容(JSX),不可以做資料請求或副作用操作 |
componentDidMount() | 元件已經真正被渲染並掛載到 DOM,可以開始做事了 |
✅ 實務上你會在這階段做什麼?
- 設定初始
state
或接收props
資料 - 發送第一次 API 請求、載入伺服器資料
- 初始化動畫、設定計時器、加入事件監聽(例如
window.addEventListener
)
💡 小提醒:大部分初次載入的邏輯都寫在
componentDidMount
裡。
更新階段(Updating)
這個階段會在元件的 props
改變,或是 state
被更新時觸發。這些改變會導致元件重新 render,更新畫面。
函式 | 說明 |
---|---|
shouldComponentUpdate(nextProps, nextState) | 讓你決定是否需要更新畫面(回傳 true or false) |
render() | 根據新的 props / state 更新畫面內容 |
componentDidUpdate(prevProps, prevState) | 畫面更新完成後可以執行的副作用邏輯 |
✅ 實務上你會在這階段做什麼?
- 比較新舊
props
/state
差異,執行條件邏輯 - 根據更新結果啟動動畫或滾動效果
- 執行 log 分析、API 上報或資料統計
💡 小提醒:
shouldComponentUpdate
是效能優化的好工具,能避免不必要的重新渲染。componentDidUpdate
很適合用來「對比前後資料做出反應」,例如當某個值改變時觸發 API。
卸載階段(Unmounting)
當元件要從畫面上被移除,會觸發這個階段。
這時候你要記得「做收尾工作」,避免留下不必要的副作用或記憶體洩漏。
函式 | 說明 |
---|---|
componentWillUnmount() | 元件即將從畫面移除,是處理清理邏輯的唯一機會 |
✅ 實務上你會在這階段做什麼?
- 清除計時器(
clearInterval
,clearTimeout
) - 移除事件監聽器(例如:
window.removeEventListener
) - 取消訂閱(WebSocket、資料串流)
- 終止未完成的 API 請求或動畫(避免報錯)
💡 小提醒:你可以把這裡想像成「元件下台收工,記得把舞台整理乾淨再走」。
額外補充說明
render()
是唯一會出現在「掛載階段」與「更新階段」的函式。
它的唯一職責是:根據資料描述畫面要怎麼顯示(回傳 JSX)。不能寫副作用邏輯,也不會操作 DOM。constructor()
與componentDidMount()
是你最常會用的初始化組合。
一個負責準備資料(像是設定state
),一個負責畫面出現後開始運作(例如 API 請求)。componentWillUnmount()
是你避免「記憶體洩漏」的關鍵環節。
尤其是使用 WebSocket、setInterval、EventListener 等「持續作用」邏輯時,一定要清掉。
小結:在對的時機做對的事
階段 | 建議行為 |
---|---|
掛載 | 設定初始資料、發送 API、加入監聽器 |
更新 | 比較資料差異、觸發動畫、副作用處理 |
卸載 | 清理資源、移除事件、停止任務 |
這些生命週期方法的設計,讓你可以不用擔心「什麼時候該做什麼」,而是按照 React 提供的節奏,把程式寫在正確的位置,讓元件更有條理、效能更好、bug 更少!
為什麼你要懂生命週期?
React 的元件不是一塊靜態 HTML,而是一個「會呼吸、會互動、會改變」的動態角色。
你寫的每一個元件,其實都是一個會隨著使用者行為和資料變化,不斷更新畫面的「活體程式碼」。
既然元件有生命,就不能亂寫!
你要懂它什麼時候出生、什麼時候會改變、什麼時候會消失,才能在對的時機做對的事。

常見錯誤情境與對應生命週期解法
❌ 錯誤 1:在 render()
裡抓資料
你可能會這樣寫:
render() {
fetch('https://example.com/data') // ❌ 錯!
return <div>內容</div>;
}
這樣做會導致什麼問題?
render()
是每次畫面更新都會被呼叫的地方- 每次更新都發送一次 API 請求,會重複抓資料爆炸
- 此時 DOM 還沒出現在畫面上,有些操作會報錯
✅ 正確作法:把這種「一開始載入資料」的邏輯,寫在 componentDidMount()
裡:
componentDidMount() {
fetch('https://example.com/data').then(...) // ✅ 正確
}
❌ 錯誤 2:API / 計時器一直跑,即使元件被移除
想像這個情境:
- 你用
setInterval()
每 3 秒更新一次數據 - 使用者切換頁面,但這個元件還在背景繼續跑
結果就是:記憶體還在被吃、效能變差,甚至可能引發錯誤
✅ 正確作法:把清除計時器的邏輯寫在 componentWillUnmount()
裡:
componentDidMount() {
this.timer = setInterval(this.doSomething, 3000);
}
componentWillUnmount() {
clearInterval(this.timer); // ✅ 元件離開前收拾乾淨
}
❌ 錯誤 3:每次更新都重做一樣的事情
你可能在 componentDidUpdate()
裡寫了這樣的邏輯:
componentDidUpdate() {
this.doAnimation(); // ❌ 每次更新都做
}
但有時資料根本沒變,或不需要執行動畫,這樣不但浪費效能,還可能出現閃爍、邏輯錯誤。
✅ 正確作法:用 shouldComponentUpdate()
搭配條件判斷:
shouldComponentUpdate(nextProps, nextState) {
return nextProps.value !== this.props.value; // ✅ 只有資料變了才更新
}
生命週期幫你做的三件事
了解元件生命週期,不只是背幾個函式名稱而已,而是幫助你「寫出健全的元件」的基礎功:
✅ 1. 管理效能
- 避免不必要的重渲染
- 控制資料更新的頻率
- 提高整體應用程式的流暢度
✅ 2. 管理副作用(side effects)
- 確保只有在需要時抓資料、操作動畫或 DOM
- 讓你的元件乾淨、好預測、不亂跑
✅ 3. 控制元件行為
- 掌握元件什麼時候該初始化、更新、清除
- 確保每個元件都有「始、有終」,不留下遺毒(像計時器、記憶體洩漏)
💬 如果你曾經寫過畫面怪閃、資料抓不回來、記憶體爆掉的 React 程式碼——很有可能就是沒有正確使用元件生命週期!
✨ 五、小結:下一步是 Hook 的世界!
現在,你已經建立了 React 元件「從誕生到離開」的基本觀念:
- React 元件不是寫完就結束,它是個活生生的東西
- 每個階段都有對應的函式讓你可以加入自訂邏輯
- 控制這些階段,就是掌握元件行為的關鍵
你可能會有以下疑問:
- 「這套生命週期方法好複雜,為什麼要記這麼多 function?」
- 「每個方法還只能做特定的事,邏輯要分來分去,好麻煩…」
- 「如果能讓我用一種方式處理所有行為該多好!」
👉 所以 React 推出了全新的做法 —— Hooks!
Hook 可以讓你用函式型元件就做到相同甚至更強大的功能,還能更靈活地封裝邏輯、拆分模組。
下一篇文章,我們就要正式進入 Hook 的世界,帶你從 class 解放,輕鬆管理元件行為。