1. React有props和state: props意味着父級分發下來的屬性,state意味着組件內部能夠自行管理的狀態,而且整個React沒有數據向上回溯的能力,也就是說數據只能單向向下分發,或者自行內部消化。javascript
2. 通常構建的React組件內部多是一個完整的應用,它本身工做良好,你能夠經過屬性做爲API控制它。可是更多的時候發現React根本沒法讓兩個組件互相交流,使用對方的數據。java
首先,redux並非必須的,它的做用至關於在頂層組件之上又加了一個組件,做用是進行邏輯運算、儲存數據和實現組件尤爲是頂層組件的通訊。若是組件之間的交流很少,邏輯不復雜,只是單純的進行視圖的渲染,這時候用回調,context就行,不必用redux,用了反而影響開發速度。可是若是組件交流特別頻繁,邏輯很複雜,那redux的優點就特別明顯了。react
redux就是用來統一管理項目中的狀態(state)。state它能夠是先後端的各類數據,也能夠是UI上的一些信息。簡單點,它就是個對象,包含了項目中可能用於改變的一些信息。redux
redux重要關注的幾點:Actions,Reducers,Store.後端
redux 的基礎概念:api
Redux 的核心是一個 store。數據結構
store 是一個 JavaScript 對象,經過 Redux 提供的 createStore(reducers) 方法建立。app
store 有兩個核心方法: getState() 和 dispatch()。ide
getState() 返回一個 JavaScript 對象,表明 store 當前的狀態。函數
獲取store中的state——當咱們用action觸發reducer改變了state時,須要再拿到新的state裏的數據,畢竟數據纔是咱們想要的。getState主要在兩個地方須要用到,一是在dispatch拿到action後store須要用它來獲取state裏的數據,並把這個數據傳給reducer,這個過程是自動執行的,二是在咱們利用subscribe監聽到state發生變化後調用它來獲取新的state數據,若是作到這一步,說明咱們已經成功了。
.dispatch() 接受一個 action 做爲參數,將這個 action 分發給全部訂閱了更新的 reducer。
action 是一個 JavaScript 對象,一般包含了 type、payload 等字段,用於描述發生的事件及相關信息(使用 Redux 中間件可讓你 dispatch 其它類型的 action,此處不展開)。
reducer 是一個 JavaScript 函數,函數簽名爲 (previousState, action) => newState,即接受 previousState 和 action 兩個參數,根據 action 中攜帶的信息對 previousState 作出相應的處理,並返回一個新的 state。
action是純聲明式的數據結構,只提供事件的全部要素,不提供邏輯。
function changeTable(index) { return { type: "channgTable", data:index } }
以上例子就是一個action,咱們不用糾結它定義個一個函數形式仍是其它,最終它就是一個對象。包含type、data或者還有其餘元素的對象。
action就是用來告訴咱們的狀態管理器須要作什麼樣的一種操做。拿以上例子來講,就是爲了作一個切換table的操做,那麼我就定義了這麼一個action。data就是你作這個操做須要處理
的一些數據等。
reducer是一個匹配函數,action的發送是全局的:全部的reducer均可以捕捉到並匹配與本身相關與否,相關就拿走action中的要素進行邏輯處理,修改store中的狀態,不相關就不對state作處理原樣返回。
以上例子就是一個reducer,它是一個會對不一樣action作出不一樣操做的函數。
如當我發出切換table的action時,就是把咱們以前定義action的data傳遞給state下的tableIndex變量,用來告訴state,我要切換table的序號。
在沒有任何操做狀況下,咱們返回初始的state。咱們不直接去改變state的值,而是返回一個新的對象,保持state的惟一性。
store負責存儲狀態並能夠被react api回調,發佈action.
這就是Store了,用來管理state的單一對象。其中有三個方法:
store.getState():獲取state,如上,通過reducer已經返回了一個新的state,那麼就能夠用該函數獲取;
store.dispatch(action):發出操做,更新state。action內有操做的類型,就能夠出發不一樣的對state的更新;
store.subscribe(listener):監聽變化,當state發生更新時,就能夠在這個函數的回調中監聽。
react-redux
React-Redux 將全部組件分紅兩大類:UI 組件(presentational component)和容器組件(container component)。
UI 組件有如下幾個特徵。
this.state
這個變量)this.props
)提供由於不含有狀態,UI 組件又稱爲"純組件",即它純函數同樣,純粹由參數決定它的值。
總之,只要記住一句話就能夠了:UI 組件負責 UI 的呈現,容器組件負責管理數據和邏輯。
react-redux在redux的基礎上,就關注兩點:Provider和connect。
Provider是一個普通組件,能夠做爲頂層app的分發點,它只須要store屬性就能夠了。它會將state分發給全部被connect的組件,無論它在哪裏,被嵌套多少層。
就是把咱們用rudux建立的store傳遞到內部的其餘組件。讓內部組件能夠享有這個store並提供對state的更新。
React-Redux 提供connect
方法,用於從 UI 組件生成容器組件。connect
的意思,就是將這兩種組件連起來。
上面代碼中,TodoList
是 UI 組件,VisibleTodoList
就是由 React-Redux 經過connect
方法自動生成的容器組件。
先接受兩個參數(數據綁定mapStateToProps和事件綁定mapDispatchToProps),再接受一個參數(將要綁定的組件自己):
connect()一共有四個參數,但我這裏只說基本的兩個,mapStateToProps和mapDispatchToProps。
mapStateToProps:簡單來講,就是把狀態綁定到組件的屬性當中。即將state
映射到 UI 組件的參數(props
),咱們定義的state對象有哪些屬性,在咱們組件的props均可以查閱和獲取。
在props中,咱們就看到了咱們綁定的狀態。它的初值就是reducer默認返回state中的值。
mapStateToProps
是一個函數。它的做用就是像它的名字那樣,創建一個從(外部的)state
對象到(UI 組件的)props
對象的映射關係。
做爲函數,mapStateToProps
執行後應該返回一個對象,裏面的每個鍵值對就是一個映射。
上面代碼中,mapStateToProps
是一個函數,它接受state
做爲參數,返回一個對象。這個對象有一個todos
屬性,表明 UI 組件的同名參數,後面的getVisibleTodos
也是一個函數,能夠從state
算出 todos
的值。
mapStateToProps
會訂閱 Store,每當state
更新的時候,就會自動執行,從新計算 UI 組件的參數,從而觸發 UI 組件的從新渲染。
mapStateToProps
的第一個參數老是state
對象,還可使用第二個參數,表明容器組件的props
對象。
使用ownProps
做爲參數後,若是容器組件的參數發生變化,也會引起 UI 組件從新渲染。
mapStateToProps 接受兩個參數,store的state和自定義的props,並返回一個新的對象,這個對象會做爲props的一部分傳入ui組件。咱們能夠根據組件所須要的數據自定義返回一個對象。ownProps的變化也會觸發mapStateToProps。
connect
方法能夠省略mapStateToProps
參數,那樣的話,UI 組件就不會訂閱Store,就是說 Store 的更新不會引發 UI 組件的更新。
mapDispatchToProps
mapDispatchToProps
是connect
函數的第二個參數,用來創建 UI 組件的參數到store.dispatch
方法的映射。也就是說,它定義了哪些用戶的操做應該看成 Action,傳給 Store。它能夠是一個函數,也能夠是一個對象。
若是mapDispatchToProps
是一個函數,會獲得dispatch
和ownProps
(容器組件的props
對象)兩個參數。
從上面代碼能夠看到,mapDispatchToProps
做爲函數,應該返回一個對象,該對象的每一個鍵值對都是一個映射,定義了 UI 組件的參數怎樣發出 Action。
若是mapDispatchToProps
是一個對象,它的每一個鍵名也是對應 UI 組件的同名參數,鍵值應該是一個函數,會被看成 Action creator ,返回的 Action 會由 Redux 自動發出。舉例來講,上面的mapDispatchToProps
寫成對象就是下面這樣。
即將用戶對 UI 組件的操做映射成 Action。在redux中介紹過,用store.dispatch(action)來發出操做,那麼咱們一樣能夠把這個方法封裝起來,即綁定到咱們的方法中。
能夠看到,這個方法return的就是一個dispatch函數,將該方法綁定到屬性上,咱們一樣能夠在props查看和調用。
這樣,咱們只要在組件中調用該屬性中的方法,就能夠發出一個特定的action,觸發reducer對state進行更新。
值得注意的是connect,Provider,mapStateToProps,mapDispatchToProps是react-redux提供的,redux自己和react沒有半毛錢關係,它只是數據處理中心,沒有和react產生任何耦合,是react-redux讓它們聯繫在一塊兒。