上次更新: 2024-07-17
這系列文章是一邊閱讀《React 思維進化:一次打破常見的觀念誤解,躍升專業前端開發者》,一邊做的筆記摘要。
由於主要是寫給自己看的筆記,所以會比較精簡,也會省略一些細節說明。從 Chapter 2 ~ Chapter 5,總共會有五篇文章。
我們通常說的 component 生命週期,準確來說是「一個 component 實例的生命週期」
主要分為三個階段:Mount, Update, Unmount。
當 component 以 React element 形式在畫面中首次出現時,就會發起 mount 流程,意味著「新畫面區塊的產生」。
流程如下:
appendChild() 放到畫面中。useEffect 裡定義的 effect 函式。是指 component 正存在於畫面中,且再次重新渲染的流程,也就是「re-render」或「reconciliation」。
無論是元件本身 state 更新而觸發的 re-render、或是因父層元件的 state 更新而觸發子元件的 re-render,update 的流程細節都是相同的。
流程如下:
useEffect 裡定義的 effect 函式。當新一次的 render 畫面結構中,有個 compoment 與前一次相比不見了,React 就會認為該 component 該被 unmount。
首先看看以下範例,當點擊 Alert 按鈕,三秒後會跳出 alert。
export default function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const handleAlertButtonClick = () => {
setTimeout(() => {
alert(`count = ${count}`);
}, 3000);
};
return (
<>
<span>Count: {count}</span>
<button onClick={increment}>+1</button>
<button onClick={handleAlertButtonClick}>Alert</button>
</>
);
}若我們先點擊 +1 把數字加到 2,再點擊 Alert 按鈕,並在三秒內趕快再點擊 +1 將數字加到 4,三秒後跳出的 alert 訊息會顯示 count = 2 還是 count = 4 呢?
答案是:count = 2,為什麼呢?
這與以下這幾個特性有關:
詳細說明可以看這篇
如前面章節所說,當我們呼叫 setCount 方法時,React 會 re-render,重新執行一次 component function 來產生新的 React element 畫面以作新舊比對。
以這邊的 Counter 例子來說,我們可以這樣理解:
// 首次 render
export default function Counter() {
// 從 useState 取出的值,把它放到新宣告的 count 變數,並且它是一個"常數",值永遠不會改變
const count = 0
...
}
// 呼叫 setState,component function 重新執行
export default function Counter() {
// 這個 count 變數與前一次宣告的 count 是不同的變數
const count = 1
...
}
// 又一次呼叫 setState,component function 再次重新執行
export default function Counter() {
const count = 2
...
}初始 render 版本的 count 是 0,點擊兩次 +1 後的 render 版本的 count 則是 2,他們都有自己版本的 state。
在每次 render 之間的 props 與 state 都是獨立、不互相影響的快照,其值永遠保值不變,像是該次 component function 執行時的區域常數。
每次 render 都會產生全新的 event handler 函式,這些函式在每次 render 間都是獨立、不相關的。
所以在這個範例中,每次 render 都會重新產生新的 handleAlertButtonClick 函式,而他們會因為閉包特性而記住自己該次版本的 props, state 資料