Introduction to Redux Selector

黃子洋
6 min readFeb 13, 2022

Redux在前端的狀態管理中算是常見的狀態管理工具,基於Flux pattern的概念來實作完成,我們可以利用Redux最基本的三項組件來達到最基本狀態管理的需求

  • Action
  • Reducer
  • Store

但這樣的缺點是,每當我們從後端帶回來一些資料存在State裡時,我們勢必想要對這些資料做一些處理來讓我們的Component來做使用,而這些資料處理的邏輯通常寫在以下這些地方

Action Creator內

每當拿回資料時,就立即把資料轉成Component想要的形式存入State中,讓Store內可以存入最少的資料。

Component中

把後端傳回的資料利用mapStateToProps帶入Component中並在裡面做處理。

通常寫在Action Creator內理論來說應該是比較好的做法,畢竟可以讓Store內存入最少的資料量,但是以上兩個方法都會把Action CreatorComponent變得非常凌亂,到處都是資料處理的邏輯。

而此時我們則需要用到Redux所提供的另一個工具Selector.

What is Selector

Selector是一個單純可以被重複使用的function,接收著state當作參數,並返回處理過得值給需要的Component

你可以在所有能拿到完整redux state的地方使用Selector function來整理資料如以下幾個地方

  • useSelector
  • mapStateToProps function
  • redux-thunk callback function (have access to getState())

Redux官方也建議使用Selector有以下三個原因

  • The actual state is easier to read
  • Less logic is needed to calculate those additional values and keep them in sync with the rest of the data
  • The original state is still there as a reference and isn’t being replaced

但現在問題來了,每當state變動時,假如在mapStateToProps function中執行一個很需要運算資源的Selector function,豈不是每更新一次store就要計算一次值嗎,此時我們可以建立memoized selector來幫我住我們進行優化。

What is Memoization

memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again

上述是memoization的定義,實作一個基本的memoized function也非常容易,只要利用Higer-Order-Function的概念來為既有的function加料就行。

以下為實作內容

  • 利用lastInput來記錄前一個函式的參數,lastOutput來記錄輸出
  • 利用shallow copy來比對前後參數有無一致,若有則輸出cached住的值
  • 若無則執行function.apply來執行該function並獲得新的value,並把新的value存入lastOuput中cache住以來進行下次的比對

若是把上述的memoized函式加料到add函式中,可以看到有memoized過個add僅僅會執行該函式一次,因為比對前後參數後一致所以第二次回傳cached在lastOutput的值而不會執行該function

Using Reselect to create memoized selectors

The createSelector API

createSelector(…inputSelectors | [inputSelectors], resultFunc, selectorOptions?)
  • inputSelectors - 可以為多個參數或一個array
  • resultFunc - 一個function參數為各個inputSelectors的返回值
  • selectorOptions

以下為官方的範例用法

from reselect official github

Reselect最大的賣點是,他預設會用shallow comparison(===)去查看前一次inputSelector所返回的值有無與現在的相等,若相等則返回cached住的value而不會重新執行一次resultFunc

createSelectorCreator

Reselect提供讓使用者客製一些相關的設定,如comparison function,某些時候我們可能想要藉由lodash的isEqual來取代(===)來比較selector前後的值,官方的github也有相關的範例

from reselect official github

Conclustion

因為最近剛好有機會來接觸Reselect,做了一些記錄希望日後在工作上對Selector如何安排有更深的體悟再來分享內容。

--

--