項目中 redux 應用

項目中redux的版本是:"redux": "^4.0.0",react

react-redux的版本:"react-redux": "^6.0.0",redux

react版本:"react": "^16.6.2",函數

createStore

相信你們在項目中都會應用到 redux,那麼在應用的過程當中可能會碰到一些問題,這裏也是在項目中遇到的一些問題的一個記錄,僅供參考spa

首先,咱們來梳理下 redux 的核心 createStore。3d

  1. createStore 是一個函數,其接收一個參數:reducer,也就是咱們所說的管理員
  2. 在函數內有三個方法,分別是 getState, dispatch, subsc-ribe
  3. dispatch 方法接收一個 action 對象,負責通知管理員,讓管理員去對狀態容器 store 中的 state 進行修改
  4. dispatch 方法還負責將以前訂閱放入隊列中的函數一一取出並執行
  5. subscribe 方法負責將調用函數時傳入的要執行的函數 fn 放入到隊列中,同時返回一個可取消這個函數 fn 的新函數
  6. getState 方法負責返回一個負責好的 state 對象

具體代碼以下:cdn

在這裏咱們能夠作簡單的分析:對象

  1. 具體的動做經過 dispatch 方法交給 reducer 管理員進行處理,管理員會返回新的 state 狀態值
  2. 想要獲取最新的 state 狀態值經過 getState 方法獲取,此時獲取到的狀態值爲一個副本
  3. 這樣作到組件獲取數據和修改數據的隔離,沒法直接對狀態 state 數據進行修改
  4. 採用隊列和訂閱發佈模式來執行新的更新

組件和狀態關聯

到如今,咱們比較清晰的理解如何獲取 state 狀態值,並能夠經過 dispatch 派發一個 action 動做對象來完成 state 狀態值的更新 可是如今有一個問題,組件觸發更新的時機在哪兒?blog

答案就在 subscribe 函數上生命週期

  1. subscribe 主要任務是訂閱函數,將要執行的函數 fn 放入隊列中,並返回一個解綁函數
  2. 在 dispatch 方法中管理員返回最新的 state 對象以後將執行隊列中的函數

那麼咱們就能夠這麼作:隊列

  1. 每一個組件在合適的生命週期方法中訂閱狀態,可經過 subscribe 方法去訂閱最新的狀態
  2. 狀態值在 reducer 管理員的修改下發生了變化,而且執行隊列中的方法,此時 stae 狀態值已是最新
  3. 狀態值爲最新值,而此時能夠經過 setState 方法去更新最新的狀態

項目應用

清晰的目錄結構

在項目裏面咱們一般會把reducer和action分開,將它們分別存放於不一樣的文件夾,每一個文件夾都有不一樣的職責。

因此咱們會對其對應的內容進行一個劃分,這樣的話,有利於咱們管理以及後續代碼的一個維護。

每一個文件夾中都有對應的reduce或者是action的文件,好比說有關於用戶的一些處理咱們能夠放在action文件夾下面的account文件裏面。

好比這樣的目錄結構:

actions 和 reducers

關於Type的定義:也就是咱們一般所說的所觸發的那個type是什麼?

一樣的咱們會把這些類型都會定義的action文件夾對應的文件中。

關於類型的幾種定義分類:

一般咱們若是說要發起Ajax請求的時候,咱們會定這樣三種類型。

第1個是關於請求也就是request:

const ACCOUNT_GET_ACCOUNTS_INFO_REQUEST = 'ACCOUNT_GET_ACCOUNTS_INFO_REQUEST'

第2個是關於請求的狀態是否成功,若是是成功的那個狀態的話,咱們會定義成success:

const ACCOUNT_GET_ACCOUNTS_INFO_SUCCESS = 'ACCOUNT_GET_ACCOUNTS_INFO_SUCCESS'

第3個是請求狀態爲失敗,這時候咱們定義成FAILED:

const ACCOUNT_GET_ACCOUNTS_INFO_FAILED = 'ACCOUNT_GET_ACCOUNTS_INFO_FAILED'

action

同時咱們會有一個對應的一個action,動做函數,動做函數接收一個dispatch這樣的一個參數。

因此說這個函數很是的簡單。只是用來觸發這樣一個動做的action,好比這裏的例子:

接下來咱們會將定義好的動做的action的這個函數以及所對應的type也就是類型,把它們所有都經過export default的方式導出去。

在外面就能夠經過import方式,獲取到對應的action的動做。

reducer

一樣的咱們也會在reducer文件夾裏面定義關於用戶對應的那些管理員函數,一樣會區分於不一樣的文件

通常來講,咱們會定一個管理員的reduce函數咱們裏面一般要對按說傳進來的type進行個區分。由於要用到action裏面的type,因此咱們須要將action引進來。

在定義的管理員函數當中,咱們會初始化狀態對象,可能初始化成一個空的對象。

同時接收一個action對象做爲參數,這個對象裏面有 type 和 payload 的屬性。咱們在函數裏面去根據 type 的值來肯定對應的狀態值是什麼。

好比上面的reducer函數,當type值爲成功時,返回的是 payload 值。

combineReducers

這樣定義好了對應的管理員函數以後,咱們能夠經過react-redux中的 combineReducers 這個方法將定好的多個管理員函數所有進行鏈接起來,而且經過export default這個方法將這些管理員函數都導出去,提供給外面進行使用。

組件中使用 action 和reducer

下面咱們來因此說在組建當中是如何使用這些reducer函數以及action

在這裏咱們要概括一下全部的action導出的都是統一的dispatch方法,而全部的reduce導出的都是對應的狀態對象。因此咱們在組件中使用這些狀態對象和dispatch方法的時候,咱們就須要用到react-redux裏面的connect函數了。

咱們使用connect函數的時候傳入對應的 mapStateToProps 以及 mapDispathToProps 這兩個方法

mapStateToProps 這個方法,將返回一個對象。其中裏面定義的東西從reducer 裏面拿取到的狀態對象。這些狀態對象經過這個方法以及connect這個方法,將狀態對象變成組件的屬性對象值。

在這裏咱們須要強調一點的是:經過connect這個方法,咱們已經將狀態對象中的屬性和組件中的 props 值進行了一個綁定。

很是重要的一點也就是若是狀態state對象中的屬性值發生了變化,那麼將會引發組件中的 props 值的變化。這也就省略了咱們去手動進行組件和狀態值的映射。這是由於connect的方法,就已經幫咱們作了這件事情。

mapDispathToProps一樣返回一個對象,它裏面定義的是組件中須要的dispatch方法。而這些方法咱們能夠經過導入對應的action中的dispatch方法進行使用,也就是說咱們經過connect這個方法將action中的函數導入到組件當中進行使用。

這裏就是組建中action的注入。

這樣咱們就能夠在組件中的prop中直接進行使用,由於這些方法或者state 對象都已經掛載到了組件的 Props 屬性上。

相關文章
相關標籤/搜索