iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Modern Web

30 天掌握 React & Next.js:從基礎到面試筆記系列 第 7

Day 7 : 為什麼不要直接修改 state ?

  • 分享至 

  • xImage
  •  

在 React 裡,你常常聽到「不要直接修改 state」。
但為什麼呢?這跟 JavaScript 的物件是 call by reference 有關。

概念解釋

在 JavaScript 中,物件和陣列都是 以 reference(參考位址)傳遞 的。

const a = { x: 1 };
const b = a;
b.x = 2;
console.log(a.x); // 2

ab 指向同一個物件,改了 ba 也會跟著變。

React 判斷 state 是否改變,也是靠 reference

  • reference 相同 → React 覺得「沒變」 → 不 re-render。
  • reference 改變 → React 才知道「有變」 → 觸發 re-render。

這就是為什麼我們要使用 不可變語法 (immutable syntax)

範例程式碼

錯誤(mutable 更新)

const [user, setUser] = useState({ name: "Andy", age: 25 });

function updateAge() {
  user.age = 26;   // 改同一個 reference
  setUser(user);   // React 以為沒變
}

正確(immutable 更新)

function updateAge() {
  setUser({ ...user, age: 26 }); // 新物件,新 reference
}

常見誤解

  • 「我明明改了值,為什麼畫面沒更新?」
    因為你只是改了舊物件,reference 沒變。
  • 「這樣不是浪費記憶體嗎?」
    有一點,但換來的是 正確性React 的效能優化

實務應用

  • 陣列:setTodos([...todos, newTodo])
  • 物件:setUser({ ...user, age: 26 })
  • 巢狀深的情況:用 Immer

小練習

判斷以下哪個正確:

const [list, setList] = useState(["a", "b"]);

// A
list.push("c");
setList(list);

// B
setList([...list, "c"]);

👉 答案:A 錯、B 對。

面試回答模板-中文

在 React 裡,物件是 call by reference。React 判斷 state 是否改變是比對 reference。
如果直接改舊 state,reference 不變,React 可能跳過更新。
所以要用不可變寫法,例如展開運算子,建立新物件或新陣列。

英文

In React, objects are call by reference. React checks state by reference.
If you mutate the old state, the reference doesn’t change, so React may skip re-rendering.
Always use immutable updates like spread to create a new object or array.

總結

  • JS 物件/陣列是 call by reference
  • React 判斷 state 是否改變,也是靠 reference。
  • 所以要用 immutable 更新 → 建立新 reference。
  • 這樣才能確保 UI 正確更新,也能啟用 React 的效能優化。

上一篇
Day 6:為什麼在 React list 中 key 這麼重要?
下一篇
Day 8:React Hook 是什麼?Hook 解決了哪些問題?
系列文
30 天掌握 React & Next.js:從基礎到面試筆記10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言