[Medium] React useEffect 與 Virtual DOM
1. What is useEffect?
什麼是
useEffect?
核心概念
useEffect 是 React 函式元件中負責管理副作用(side effects)的 Hook。它會在元件渲染之後執行非同步資料請求、訂閱、DOM 操作或手動同步狀態,對應 class 元件的 componentDidMount、componentDidUpdate 與 componentWillUnmount 等生命週期方法。
常見用途
- 取得遠端資料並更新元件狀態
- 維護訂閱或事件監聽(如
resize、scroll) - 與瀏覽器 API 互動(如更新
document.title、操作localStorage) - 清除前一次渲染遺留的資源(如取消請求、移除監聽器)
點此展開基本使用範例
import { useEffect, useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `點擊次數:${count}`;
});
return (
<button type="button" onClick={() => setCount((prev) => prev + 1)}>
點我
</button>
);
}
2. When does useEffect run?
useEffect何時會執行?
useEffect 的第二個參數是相依陣列(dependency array),用來控制副作用的執行時機。React 會逐一比較陣列中的每個值,在偵測到變化時重新執行副作用,並於下一輪執行前觸發清除函式。
2.1 常見依賴模式
// 1. 每次渲染後執行(含第一次)
useEffect(() => {
console.log('任意 state 改變都會觸發');
});
// 2. 僅在初次渲染時執行一次
useEffect(() => {
console.log('只會在 component mount 時執行');
}, []);
// 3. 指定相依變數
useEffect(() => {
console.log('僅在 selectedId 改變時觸發');
}, [selectedId]);
2.2 清除函式與資源回收
useEffect(() => {
const handler = () => {
console.log('監聽中');
};
window.addEventListener('resize', handler);
return () => {
window.removeEventListener('resize', handler);
console.log('解除監聽');
};
}, []);
上述範例運用清除函式解除事件監聽。React 會在元件卸載或依賴變數更新之前先執行清除函式,確保不留下記憶體洩漏與重複監聽。
3. What is the difference between Real DOM and Virtual DOM?
真實 DOM 與虛擬 DOM 的差異是什麼?
| 比較面向 | Real DOM(真實 DOM) | Virtual DOM(虛擬 DOM) |
|---|---|---|
| 結構 | 由瀏覽器維護的實體節點 | 由 JavaScript 物件描述的節點 |
| 更新成本 | 直接操作會觸發排版與重繪,成本高 | 先計算差異再批次套用,成本低 |
| 更新策略 | 立即反映至畫面 | 先在記憶體建立新樹再比較差異 |
| 擴充性 | 需手動控制更新流程 | 可以插入中介邏輯(Diff、批次) |