React 是怎麼 re-render 畫面的,你知道嗎?
就是它會去比較 prev state 跟 current state 呀!兩個不同就 re-render 囉。(欸嘿,這面試題太簡單啦!我應該回答的很好。)
喔?那你說說看,它怎麼比較新舊 state 的呢?
就是 `useState()` 裡面有提供 callback function 呀! 寫一個 `(prev) => { // ... }` 這樣就能比較了。(經典的 counter 不會動該怎麼修的題目嘛!我知道!)
嗯嗯…。(鍵盤疾打,在面試官筆記內輸入「這位面試者似乎還停留在只會「使用 React」的程度,對原理瞭解得較淺。」)
…。(啊咧咧!怎麼氣氛好像挺微妙的!可是我答得很好呀?)
先備知識
這些觀念還不清楚的要先看唷。
先承認,開頭的小劇場就是我真實發生過的事。
每次呼叫 setState(),React 會用 Object.is() 比較新舊 state。
對 Primitive 來說這沒問題,值不一樣就是不一樣。
但對 Object / Array,Object.is 比的是記憶體位址,不是內容。
js
const a = { name: 'Yuzu' };
const b = a;
b.name = 'Mochi';
Object.is(a, b); // true,位址一樣,React 認為沒變
直接 mutate — 畫面不更新
const [cat, setCat] = useState({ name: 'Yuzu' });
// ❌ 錯誤寫法
const rename = () => {
cat.name = 'Mochi'; // 直接改,位址沒變
setCat(cat); // React 比較後:一樣,不 re-render
};
回傳新物件 — 畫面正確更新
const [cat, setCat] = useState({ name: 'Yuzu' });
// ✅ 正確寫法
const rename = () => {
setCat({ ...cat, name: 'Mochi' }); // 新物件,位址不同
};
spread 建立一個新物件,位址不同,Object.is 回傳 false,React 知道 state 變了,才會 re-render。
Array 同理,用 map、filter、[...arr] 而不是直接 push 或 splice:
// ❌
list.push(newItem);
setList(list);
// ✅
setList([...list, newItem]);