react-redux

react

 

1. React有props和state: props意味着父級分發下來的屬性,state意味着組件內部能夠自行管理的狀態,而且整個React沒有數據向上回溯的能力,也就是說數據只能單向向下分發,或者自行內部消化。javascript

2. 通常構建的React組件內部多是一個完整的應用,它本身工做良好,你能夠經過屬性做爲API控制它。可是更多的時候發現React根本沒法讓兩個組件互相交流,使用對方的數據。java

而後這時候不經過DOM溝通(也就是React體制內)解決的惟一辦法就是提高state,將state放到共有的父組件中來管理,再做爲props分發回子組件。
 
3. 子組件改變父組件state的辦法只能是經過onClick觸發父組件聲明好的回調,也就是父組件提早聲明好函數或方法做爲契約描述本身的state將如何變化,再將它一樣做爲屬性交給子組件使用。
 
4. 爲了面臨全部可能的擴展問題,最容易想到的辦法就是把全部state集中放到全部組件頂層,而後分發給全部組件。
 
5. 爲了有更好的state管理,就須要一個庫來做爲更專業的頂層state分發給全部React應用,這就是Redux。

先簡單說一下redux和react是怎麼配合的。react-redux提供了connect和Provider兩個好基友,它們一個將組件與redux關聯起來,一個將store傳給組件。組件經過dispatch發action,store根據action的type屬性調用對應的reducer並傳入state和這個action,reducer對state進行處理並返回一個新的state放入store,connect監聽到store發生變化,調用setState更新組件,此時組件的props也就跟着變化。

redux

首先,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:

  action是純聲明式的數據結構,只提供事件的全部要素,不提供邏輯。

function changeTable(index) { return { type: "channgTable", data:index } }
以上例子就是一個action,咱們不用糾結它定義個一個函數形式仍是其它,最終它就是一個對象。包含type、data或者還有其餘元素的對象。
action就是用來告訴咱們的狀態管理器須要作什麼樣的一種操做。拿以上例子來講,就是爲了作一個切換table的操做,那麼我就定義了這麼一個action。data就是你作這個操做須要處理
的一些數據等。

二、Reducer :

reducer是一個匹配函數,action的發送是全局的:全部的reducer均可以捕捉到並匹配與本身相關與否,相關就拿走action中的要素進行邏輯處理,修改store中的狀態,不相關就不對state作處理原樣返回。

以上例子就是一個reducer,它是一個會對不一樣action作出不一樣操做的函數。

如當我發出切換table的action時,就是把咱們以前定義action的data傳遞給state下的tableIndex變量,用來告訴state,我要切換table的序號。

在沒有任何操做狀況下,咱們返回初始的state。咱們不直接去改變state的值,而是返回一個新的對象,保持state的惟一性。

三、Store:

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)。

1、UI 組件

UI 組件有如下幾個特徵。

  • 只負責 UI 的呈現,不帶有任何業務邏輯
  • 沒有狀態(即不使用this.state這個變量)
  • 全部數據都由參數(this.props)提供
  • 不使用任何 Redux 的 API

由於不含有狀態,UI 組件又稱爲"純組件",即它純函數同樣,純粹由參數決定它的值。

 

2、容器組件

  • 負責管理數據和業務邏輯,不負責 UI 的呈現
  • 帶有內部狀態
  • 使用 Redux 的 API

 

總之,只要記住一句話就能夠了:UI 組件負責 UI 的呈現,容器組件負責管理數據和邏輯。

react-redux在redux的基礎上,就關注兩點:Provider和connect。

一、Provider:

Provider是一個普通組件,能夠做爲頂層app的分發點,它只須要store屬性就能夠了。它會將state分發給全部被connect的組件,無論它在哪裏,被嵌套多少層。

就是把咱們用rudux建立的store傳遞到內部的其餘組件。讓內部組件能夠享有這個store並提供對state的更新。

 

二、connect:

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

mapDispatchToPropsconnect函數的第二個參數,用來創建 UI 組件的參數到store.dispatch方法的映射。也就是說,它定義了哪些用戶的操做應該看成 Action,傳給 Store。它能夠是一個函數,也能夠是一個對象。

若是mapDispatchToProps是一個函數,會獲得dispatchownProps(容器組件的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讓它們聯繫在一塊兒。

相關文章
相關標籤/搜索