1 回答

TA貢獻1777條經驗 獲得超3個贊
這個問題要從很多方面來觀察,我用以下的說明來簡單解釋。
首先,Redux作者在最初演示時,就有提及它的核心設計的來源有兩個:
Redux = Elm + Flux
Redux大量借鏡了Elm語言的設計邏輯,以及函數編程(functional programming, FP)的編程風格,純函數是FP中的重要核心,FP是什么?用下面的一句話來說明,摘譯自這篇教程文章:
函數編程就是只使用純函數與不可改變的值來撰寫軟體應用的一種方式
實際上因為React本身也有用到FP的一些設計概念,在官網上有一段對于函數式元件的說明是這樣寫的,這是在講解組件對于自己本身props的嚴格規則。出自官網這里:
所有的React組件必須運作得就像相對于它們props(屬性)的純函數
由此看來,Redux雖然是用了純函數來作為框架的主要內部設計,其實它在某方面只是順應了React的設計,并且更改進了這些的應用。
那為何要使用reducer?這要從另一個Redux的組成分子Flux看起。Flux是Facebook中設計出來,為了解決React應用的數據流的一種樣式(或架構),細節部不多說。Redux中許多設計,都可以看到Flux架構的影子。理所當然的,Flux是React開發團隊或核心周邊的應用團隊設計的,自然很清楚React的核心是怎么運作,實際上的問題關鍵在何處,當然也知道怎么讓數據流架構起來是最合適的。
Flux中的數據流運作,最終還是需要對React組件進行state的更動,才能發動重新渲染,而在React中的設計,state不能直接更動,必需透過setState方法,setState方法除了傳給它一個要更動的對象值之外,還有一種用法是給它一個函數當傳參,公式如下(出自官網的這里):
function(state, props) => newState
這公式就是一個reducer函數。React運用了Diff算法,對于目前state與要更動的state進行演算,來達成虛擬DOM的重渲染運作過程。所以,React的算法需要兩個值,一個是當前的state,另一個是即將要更動的state值,這樣它才能用算法進行演算。
返回來看Flux中的架構,里面在工具中有一個名稱為ReduceStore的東西,Flux的數據核心是名稱為store,這個ReduceStore是一個更進化版本的store,它在說明中有一個叫作reduce的方法,說明如下:
reduce(state: T, action: Object): T 歸納(Reduces)目前的state(狀態)與一個action(動作)到新的store中的state(狀態)。所有的子類都需要實作這個方法。這個方法必須是純粹而是無副作用。
那為何要用這個進化的ReduceStore?它最后有說明一段:
不需要發送更動事件 注意所有繼承自ReduceStore的store,不需要手動發送(emit)在reduce()中的更動事件...state(狀態)會自動地比對在每個dispatch(發送)之前與之后,與自動地作發送更動事件...
ReduceStore的設計與Redux最一開始的版本差不多是同時間發布的,開發者之間彼此有交流。
以上說明了這么多,回過頭來看一下Redux中的reducer與純函數的必要性。因為這里的說明需要上面的前情提要。
Redux中的reducer的公式是像下面這樣的:
(previousState, action) => newState
它長得與React中的setState公式有些相似,與Flux中的ReduceStore中的reduce方法根本就一樣。
所以你可以大概知道,Redux為什么要用純函數的reducer了,因為Redux原本就是一種Flux架構的改進簡化作法,它使用的是ReduceStore類似的機制,可以自動地作一些原本可能很復雜的工作。
所以在一開始創作Redux時,Redux作者有寫一篇博客,談到他準備要對Flux進行改進的想法,其中就有結論一些方向,例如:
making the Stores stateless
這說的Stores無狀態就是寫成純函數的reducer。
Stores and actions are just pure functions. They are easily testable in isolation.
這里的Stores指的是現在的純函數的reducer,actions指的是Action Creators。
最后回覆問題如下:
為什么會有這樣的規定(為什么redux中的reducer一定要是純函數)?考慮是什么?
就是為了改進Flux的有些分離不清的架構,簡化一些其中的流程。
不過,這只是其中一種解決方案,但不是唯一的只有一種。只是時至今日,你所看到接受度最高與最熱門的是Redux。
如果在reducer里做了其它事情會怎樣?
目前來說Redux中的reducer必定要是純函數,如果有副作用寫在里面,整個機制運作不起來。
Redux會報錯中斷執行,警告里面有出現你用了副作用的代碼在reducer里。(所以副作用可以嚴格檢查的…而且有分微量、通常、重度的副作用)
添加回答
舉報