iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 23
1
Modern Web

I Want To Know React系列 第 23

I Want To Know React - 初探提升 state

當一個 component 需要存取修改一份資料 / 狀態的時候,通常我們會把這份資料 / 狀態做成 state,讓該 component 自己維護資料的內容。

然而常常會出現多個 component 需要存取修改同一份資料 / 狀態的狀況。在這種情形下應該怎麼處理呢?是否要複製一份相同的資料作為其他 component 的 state 呢?

答案是:State 應該要保持一份就好,另外,此 state 應要被提升到最靠近這些 component 的共同祖先 component 上。

在解釋為什麼要這樣做之前,先讓我們了解一下 React 對資料處理理念。

React 資料處理理念

React 十分重視對於資料與狀態的處理方式。

現代的網頁中,為了講求更好的使用者體驗,並滿足大型網站的開發需求,資料與狀態處理變的日益困難。而一個好的資料處理方式可以大大降低維護專案的難度。

為了達到易維護資料與狀態的目的,React 提倡以下兩個資料與狀態的處理理念:

  • Top-down data flow(Unidirectional data flow,單一資料流)
  • Single Sourrce Of Truth

以下將逐一介紹。

Single source of truth

第一個理念是 Single source of truth,React 主張一份資料只應該維護一份。

理想上,一份資料 Single source of truth 的範圍應該橫跨整個專案。

也就是說,不論對於下層、同層、上層 component 都不應該重複擁有同一份資料。

另外,能被計算出來的資料不應該另外存成另一份資料,只應保留最原始的那份即可。

舉例來說,如果今天有兩份清單,一份是原始清單,一份是使用者搜尋後過濾出來的清單,則應該只保留原始清單就好。因為只要有原始清單,我們就隨時隨地可以計算出任何使用者想要過濾的內容,因此,同時存下搜尋過濾出來的清單就較沒有必要。

Single source of truth 的優點會有幾個:

  • 由於只要維護一份資料,因此更新資料時會變的較輕鬆

  • 避免資料不一致的問題

    當同樣資料的份數變多時,很容易發生的問題就是其中幾份資料漏改或錯改,導致資料不一致的問題。

  • 由於只有一份資料,因此取用資料時不會有不知道應該取用哪份資料的問題

    承接上一點,當有多份同樣卻不統一的資料時,就很難知道哪份資料才是可信任的。常見的狀況是每個地方都取用不同份的資料,使整個專案中的資料混亂不堪。

Single source of truth 也有缺點,例如可能會導致效能較差,因為使用資料時常常都需要被重新計算,不能暫存起來。但整體來說,single source of truth 絕對是讓資料易於維護的關鍵點之一。

Top-down data flow(Unidirectional flow)

第二個理念是 Top-down data flow,React 主張一份資料只應該由上而下傳遞,且一份資料只應在一個地方修改。

也就是說,一份資料被創建出來後就只能往下層 component 傳遞,無法往上層 component 傳遞。整個資料傳遞呈現由上至下的流向,所以稱做 top-down flow。

如果今天下層 component 想要更改資料,則需往上層 component 透過 event 發送 "更改請求" 。然而最後決定是否修改資料的還是持有資料的 component。

Top-down flow 會有以下維護上的好處:

  • 因為資料流必定是由上至下的,因此只要往上找就可找到資料源頭

  • 資料必須在創建的地方修改,如此可以大大減少追查資料更新位置的成本

    如果一份資料可以任何 component 中修改,則資料更新錯誤時找到實際更新資料的位置會變的十分困難,因為可能性太多,每個地方都需要確認是否有改動資料,造成維護上極大的困難。

在 React 中,top-down data flow 的實踐方式就是 stateprop 以及 event

State(資料)會由一個 component 創建出來,並可能作為下層 component 的 prop 傳入。另一方面,接收 prop 的 component 只能取用資料而不能修改。如果下層的 component 有任何修改 state 的需求,則需透過 event 向上傳遞請求。創建 state 的 component 收到 event 後就可以依照 event 的內容選擇如何更新 state。整個 top-down data flow 就這樣被實踐出來。

雖然缺點是樣板(Boilerplate)程式碼會比較多,但可以有效減少 bug 並使追查資料流向變得很簡單。

總結 React 資料處理理念

總結 React 處理資料的理念,single source of truth 是限制資料的存在份數,而 top-down flow 是限制資料的流向與改動資料的地方。限制了過多資料處理方式的可能性後,將大大降低維護的難易度。

提升 state

概念

回到開頭所問的,當多個 component 需要修改同一個資料(state)時,應該怎麼處理呢?回顧一下剛剛介紹的內容,答案應該呼之欲出了。

資料應該要同時符合兩個概念:

  • Single Source Of Truth
  • Top-down data flow

也就是說:

  • 該資料只能有一份
  • 該資料必須由上層往下傳遞

所以結論就是:

應該把共有資料提升到有使用到此資料的 component 的共有祖先 state 中,以達到 Single Souce Of Truth 的概念。

接著,如果下層 component 需要的話,就使用 prop 的方式將 state 資料傳遞下去。

如果下層 component 需要通知上層 component 改動,就透過 event 發送通知。

如此就可以同時達到 Top-down data flow 了。

而這就是 提升 State 的概念以及為何這麼做的原因。

使用時機

從上面的介紹可以知道,只要有多個 component 共用 state 的狀況,就應該把此 state 提升到 component 的共用祖先上。

然而有時候這種功能也可能藉由 Context 或是 Redux 等管理工具達成。

優點

因為提升 state 技巧結合了 top down data flow 與 single source of truth 的概念,因此提升 state 技巧擁有兩項理念的所有優點,包括:

  • 更新資料時會變的較輕鬆(Single source of truth)
  • 不會有資料不一致的問題(Single source of truth)
  • 取用資料時不會有不知道應該取用哪份資料的問題(Single source of truth)
  • 只要往上找就可找到資料源頭(Top-down data flow)
  • 資料必須在創建的地方修改,大大減少追查資料更新位置的成本(Top-down data flow)

缺點

同時,提升 state 也會包含兩項理念的缺點:

  • 每次資料都必須重新計算,在某些情況下可能效能較差(Single source of truth)

  • Boilerplate 程式較多,傳遞太多層時會造成維護不易(Top-down data flow)

    這個缺點可以用 Context 來解決。Context 將在往後章節提及。

小結

在這個章節中,我們介紹了提升 state 的概念以及為什麼這麼做的原因。

需要提升 state 是因為 React 有兩個處理資料的理念:

  • Single source of truth
  • Top-down data flow

透過實踐這兩個理念可以大大提高程式的可維護性,而提升 state 就是這兩個概念的實踐方式。

下個章節中,我們將使用範例實際示範如何提升 state。

參考資料


上一篇
I Want To Know React - Uncontrolled component
下一篇
I Want To Know React - 提升 state 練習
系列文
I Want To Know React30

尚未有邦友留言

立即登入留言