iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Modern Web

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

Day 20 setState 背後的機制(Class, Function)?

  • 分享至 

  • xImage
  •  

本篇內容參考自 Overreacted 網站的 "How Does setState Know What to Do?"

在 Class component 中常寫 this.setState(...),卻沒想過背後其實做了很多事。Overreacted 那篇文章,就是解釋這條線怎麼走:setState 是怎麼通知 React 去更新 UI 的。今天我們來拆給你聽。

概念解釋

  • 當你建立一個 class component instance 時,renderer 會把一個 updater 欄位注入到該 instance。

  • React.ComponentsetState 方法裡,其實做的就是呼叫這個 updater 的 enqueueSetState

    this.updater.enqueueSetState(this, partialState, callback);
    

    這就是把「我要更新什麼」的請求交給 renderer 處理。

  • 也就是說:setState 自己不做 state 合併、diff、render,這些工作交給 renderer / reconciler 處理。

  • 文章最後也提到:Hooks 的 useState 在抽象層上與 class 的 setState 是類似的——它也會把更新請求交給 dispatcher / renderer 處理。

錯誤版本 vs 正確版本

  • 錯誤版本:指的是一段看起來合理、常被誤認是 setState 機制的程式碼,但它 忽略了背後委派 / updater / renderer 注入 的真正角色。這種版本比較偏「表面用法」,不幫助理解背後機制。
  • 正確版本:雖然也不是真正的完整架構,但它揭示了那條「由 setState 委派給 updater」的管線,讓你看到機制的核心。

錯誤版本(誤解寫法)

class MyComp extends React.Component {
  increment() {
    this.setState({ count: this.state.count + 1 });
    // 然後想立刻讀 this.state.count、認為 UI 會馬上變更。
  }
}

這段程式碼在日常開發中沒問題,但當你把它拿來當作「理解 setState 機制」的版本,就不夠。它隱藏了很多細節:

  • 它沒有告訴你 setState 背後有 updater 在動作。
  • 它讓人可能誤以為 setState 自己會做所有事情(合併 state + 觸發 re-render + 更新 UI)。
  • 它忽略「更新是排程機制,不一定同步」這種 nuance。

所以我們把它稱為「錯誤版本」——不是說它原始碼錯,只是作為機制解釋來說,不夠完整。

正確版本(示意代理寫法)

class MyComp extends React.Component {
  setState(partial, cb) {
    this.updater.enqueueSetState(this, partial, cb);
  }
}

這段程式碼並不是完整的 React source code,但它幫你看到核心:

  1. setState 並不自己做更新,而是呼叫 updater.enqueueSetState(...)
  2. updater 是在 instance 上被注入的,來自 renderer。
  3. 那個 enqueueSetState 就是這條請求進入更新流程的入口。

這樣你就能理解:setState 是一個委派(delegation)的動作,不是「自己做所有事」。

常見錯誤 / 誤解

  • 誤以為 setState 馬上改 state + 立刻更新 UI。
  • 誤以為 Hooks (useState) 與 class 的 setState 是完全不同,忽略抽象層的共通機制。

實務應用

  • 讓你有能力 debug state 更新失敗或 UI 不更新的 bug。
  • 在跨平台開發(Web + React Native)時,理解這機制能幫你看 log、定位問題。

面試回答

中文

在 class component 中,呼叫 this.setState(...) 並不會自己做 UI 更新。實際上,在 component instance 上有一個由 renderer 注入的 updater 欄位。setState 會呼叫 this.updater.enqueueSetState(...),把更新請求傳給 renderer。那個 renderer(像是 react-domreact-native)負責排程、合併 state、diff UI,最後重新渲染。對於 Hooks 裡的 useState,抽象設計層面也非常類似:它也是把更新委派給 dispatcher / renderer 去處理。

英文

In React class components, calling this.setState(...) doesn’t directly update the UI. Instead, each instance has an updater injected by the renderer (like react-dom or react-native).
setState internally calls something like this.updater.enqueueSetState(...), forwarding the partial state or callback.
The renderer’s reconciler then handles merging state, diffing, and rendering.
Hooks’ useState works similarly at the abstraction level — it delegates state updates to the renderer via dispatcher / updater.

總結

  • React 把 UI 更新邏輯從核心中抽離,由不同平台的 renderer 實作。
  • 在 class component 裡,setState 本身只是委派:呼叫 instance 上注入的 updater.enqueueSetState(...)
  • Hooks 的 useState 在抽象層與 class 的 setState 有類似的 delegation 機制。

上一篇
Day 19:function component vs Class component 的差異
系列文
30 天掌握 React & Next.js:從基礎到面試筆記20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言