本篇內容參考自 Overreacted 網站的 "How Does setState Know What to Do?"
在 Class component 中常寫 this.setState(...)
,卻沒想過背後其實做了很多事。Overreacted 那篇文章,就是解釋這條線怎麼走:setState
是怎麼通知 React 去更新 UI 的。今天我們來拆給你聽。
當你建立一個 class component instance 時,renderer 會把一個 updater
欄位注入到該 instance。
在 React.Component
的 setState
方法裡,其實做的就是呼叫這個 updater 的 enqueueSetState
:
this.updater.enqueueSetState(this, partialState, callback);
這就是把「我要更新什麼」的請求交給 renderer 處理。
也就是說:setState
自己不做 state 合併、diff、render,這些工作交給 renderer / reconciler 處理。
文章最後也提到:Hooks 的 useState
在抽象層上與 class 的 setState
是類似的——它也會把更新請求交給 dispatcher / renderer 處理。
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)。所以我們把它稱為「錯誤版本」——不是說它原始碼錯,只是作為機制解釋來說,不夠完整。
class MyComp extends React.Component {
setState(partial, cb) {
this.updater.enqueueSetState(this, partial, cb);
}
}
這段程式碼並不是完整的 React source code,但它幫你看到核心:
setState
並不自己做更新,而是呼叫 updater.enqueueSetState(...)
。updater
是在 instance 上被注入的,來自 renderer。enqueueSetState
就是這條請求進入更新流程的入口。這樣你就能理解:setState
是一個委派(delegation)的動作,不是「自己做所有事」。
setState
馬上改 state + 立刻更新 UI。useState
) 與 class 的 setState
是完全不同,忽略抽象層的共通機制。中文
在 class component 中,呼叫
this.setState(...)
並不會自己做 UI 更新。實際上,在 component instance 上有一個由 renderer 注入的updater
欄位。setState
會呼叫this.updater.enqueueSetState(...)
,把更新請求傳給 renderer。那個 renderer(像是react-dom
、react-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 anupdater
injected by the renderer (likereact-dom
orreact-native
).setState
internally calls something likethis.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.
setState
本身只是委派:呼叫 instance 上注入的 updater.enqueueSetState(...)
。useState
在抽象層與 class 的 setState
有類似的 delegation 機制。