前言
一直對於redux
處於一知半解的狀態,有幸看到Wang Namelos老師在知乎上一段回答,認真讀了三遍,猶如醍醐灌頂,推薦給大家,內容如下:
Redux
從需求出發,看看使用React
需要什麼:
React
有props
和state
:props
意味著父級分發下來的屬性,state
意味著元件內部可以自行管理的狀態,並且整個React
沒有資料向上回溯的能力,也就是說資料只能單向向下分發,或者自行內部消化。理解這個是理解React
和Redux
的前提。- 一般構建的
React
元件內部可能是一個完整的應用,它自己工作良好,你可以通過屬性作為API控制它。但是更多的時候發現React
根本無法讓兩個元件互相交流,使用對方的資料。然後這時候不通過DOM
溝通(也就是React
體制內)解決的唯一辦法就是提升state
,將state
放到共有的父元件中來管理,再作為props
分發回子元件。 - 子元件改變父元件
state
的辦法只能是通過onClick
觸發父元件宣告好的回撥,也就是父元件提前宣告好函式或方法作為契約描述自己的state
將如何變化,再將它同樣作為屬性交給子元件使用。這樣就出現了一個模式:資料總是單向從頂層向下分發的,但是隻有子元件回撥在概念上可以回到state
頂層影響資料。這樣state
一定程度上是響應式的。 - 為了面臨所有可能的擴充套件問題,最容易想到的辦法就是把所有
state
集中放到所有元件頂層,然後分發給所有元件。 - 為了有更好的
state
管理,就需要一個庫來作為更專業的頂層state
分發給所有React
應用,這就是Redux
。讓我們回來看看重現上面結構的需求:
- 需要回撥通知
state
(等同於回撥引數) ->action
- 需要根據回撥處理 (等同於父級方法) ->
reducer
- 需要
state
(等同於總狀態) ->store
對Redux
來說只有這三個要素:
action
是純宣告式的資料結構,只提供事件的所有要素,不提供邏輯。reducer
是一個匹配函式,action
的傳送是全域性的:所有的reducer
都可以捕捉到並匹配與自己相關與否,相關就拿走action
中的要素進行邏輯處理,修改store
中的狀態,不相關就不對state
做處理原樣返回。store
負責儲存狀態並可以被react api
回撥,釋出action
.
當然一般不會直接把兩個庫拿來用,還有一個binding
叫react-redux
, 提供一個Provider
和connect
。很多人其實看懂了redux
卡在這裡。
-
Provider
是一個普通元件,可以作為頂層app
的分發點,它只需要store
屬性就可以了。它會將state
分發給所有被connect
的元件,不管它在哪裡,被巢狀多少層。 -
connect
是真正的重點,它是一個科裡化函式,意思是先接受兩個引數(資料繫結mapStateToProps
和事件繫結mapDispatchToProps
),再接受一個引數(將要繫結的元件本身)。
mapStateToProps
:構建好Redux
系統的時候,它會被自動初始化,但是你的React
元件並不知道它的存在,因此你需要分揀出你需要的Redux
狀態,所以你需要繫結一個函式,它的引數是state
,簡單返回你關心的幾個值。
mapDispatchToProps
:宣告好的action
作為回撥,也可以被注入到元件裡,就是通過這個函式,它的引數是dispatch
,通過redux
的輔助方法bindActionCreator
繫結所有action
以及引數的dispatch
,就可以作為屬性在元件裡面作為函式簡單使用了,不需要手動dispatch
。這個mapDispatchToProps
是可選的,如果不傳這個引數redux會簡單把dispatch
作為屬性注入給元件,可以手動當做store.dispatch
使用。這也是為什麼要科裡化的原因。
做好以上流程Redux
和React
就可以工作了。簡單地說就是:
- 頂層分發狀態,讓
React
元件被動地渲染。 - 監聽事件,事件有權利回到所有狀態頂層影響狀態。