React Hooks 之 useState 的陷阱

Ryan Hsu
Its Ok to Make Mistakes
4 min readMar 26, 2019
Photo by Simone Acquaroli on Unsplash

一般來說,正常的 React Component 重新 render 的規則是

只要 State 或是 Props 有改變,一律重繪

這個規則,不管是 Class Component 或是 Functional Component 都是一樣的。

這個主題在 為什麼我的 React Component 畫面不會更新 ? 一文中有提到,但這個問題應該是比較多人在使用 Hooks 上會遇到問題的,所以特別抽出一篇文章重新解釋一次。

為什麼會一律重繪?

原因是 React 的生命週期 shouldComponentUpdate 永遠都是回 true 的關係

什麼是 shouldComponentUpdate?

React Component 的生命週期之一,讓 React Component 知道自己該不該更新。

要如何讓 React Component 某些情況不更新來增加效能?

  • 自己實作 Class Component 的 shouldComponentUpdate (不推薦,通常只會讓程式可讀性降低,與增加造成查問題的困難度)
  • Class Component 使用 Pure Component
  • Functional Component 使用 memo API

後兩者都是使用 Pure 策略,官方幫你在 shouldComponentUpdate 實作「淺層比較 Shallow Equal」,達到更好的效能。

如果你還不知道什麼是淺層比較 Shallow Equal,請看:Shallow Compare

另外, Pure 策略並不是效能的萬靈藥,請看:React 巢狀 Component 效能優化

useState 有什麼陷阱?

使用 React useState API ,讓我們的 Functional Component 可以有 State 的能力,但我們如果不 實作 memo API,我們預期應該是要跟 React Class Component 一樣的行為「一律重繪」。

範例

你會發現 State 雖然更新了,但畫面卻沒有改變,為什麼?

因為 Hooks 的 useState 實作

抽絲剝繭,跑去看了 React 原始碼,原因其實出在 useState 的實作,最後會走向 shallow Equal 的方法,「判斷之前的狀態與之後的狀態」來決定是不是要更新 Component,所以其實 useState 自帶 shallowEqual 的比較,請務必特別注意。

Hi 我是 Ryan,如果這篇文章有幫助到你,請你不吝嗇的給予我鼓掌,那將是我進步的動力!👏

另外,你知道 Medium 一篇文章拍手其實可以拍 50 下嗎?如果你願意,請賜我掌聲,謝謝!

--

--