深入淺出React和Redux

Jsp發表於2018-06-08

UI=render(data)

深入淺出React和Redux

一:prop和state的對比

總結prop和state的區別:

  • prop用於定義外部介面,state用於記錄內部狀態
  • prop的賦值在外部世界使用元件時,state的賦值在元件內部
  • 元件不應該改變prop的值,state存在的目的就是讓元件來改變的。

this.setState()函式所做的事情,首先是改變this.state的值,然後驅動元件更新過程。

二:元件的生命週期

生命週期經歷如下三個過程:

  • 裝載過程Mount:元件第一次在DOM樹中渲染的過程。  componentWillMount   componentDidMount
  • 更新過程Update:當元件被重新渲染的過程    componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、componentDidupdate
  • 解除安裝過程Unmount:元件從DOM中刪除的過程   componentWillUnmount

裝載過程

1、constructor

建構函式:有狀態的元件才需要定義,目的是:

  • 初始化state
  • 繫結成員函式的this環境

2、render

render函式不做實際的渲染動作,只是然後一個JSX的描述結構,最終由React來操作渲染。render函式是一個純函式。

更新過程

1、componentWillReceiveProps(nextProps)

只要父元件的render函式被呼叫,在render函式裡面被渲染的子元件就會經歷更新過程,不管父元件傳給子元件的props有沒有改變,都會觸發componentWillReceiveProps函式。

通過this.setState方法觸發的更新過程不會呼叫這個函式。

2、shouldComponentUpdate(nextProps,nextState)

render函式返回結果將用於構造DOM物件,而shouldComponentUpdate函式返回一個布林值,告訴React庫這個元件在這次更新過程中是否要繼續。

通過this.setstate函式引發更新過程,並不是立刻更新元件的state值,在執行到函式shouldComponentUpdate的時候,this.state依然是this.setState函式執行之前的值。

三:元件向外傳遞資料

父到子元件:prop

子到父元件:將函式像其他物件一樣作為prop的值從父元件傳遞給子元件,又可以被子元件作為函式呼叫。

四:Redux

React元件中state和prop的侷限:state沒有全域性狀態,prop一層一層的傳遞。

Redux的基本原則:

  • 唯一資料來源
  • 保持只讀狀態
  • 資料改變只能通過純函式完成

1、唯一資料來源

唯一資料來源指的是應用的狀態資料應該只儲存在唯一的一個store上

2、保持狀態只讀

不能直接修改狀態,要修改store的狀態,必須要通過派發一個action物件完成。驅動使用者介面渲染,就要改變應用的狀態,但是改變狀態的方法不是去修改狀態上值,而是建立一個新的狀態物件返回給Redux,由Redux完成新的狀態的組裝。

3、資料改變只能通過純函式完成

reducer(state,action),redux的reducer只負責計算狀態,不負責儲存狀態。

Redux中的每個action建構函式都返回一個action物件,action建構函式只負責建立物件,要派發action就需要呼叫store.dispatch函式。

五:容器元件和傻瓜元件

在Redux框架下,一個React元件基本就是完成以下兩個功能:

  • 外層(容器元件):和Redux Store打交道,讀取Store的狀態,用於初始化元件的狀態,同時還要監聽Store的狀態改變;當Store狀態發生變化時,需要更新元件狀態,從而驅動元件重新渲染;當需要更新Store狀態時,就要派發action物件。
  • 內層(展示元件):根據當前props和state,渲染出使用者介面。

1、元件Context

所謂Context,就是‘上下文環境’,讓一個樹狀元件上所有元件都能訪問一個共同的物件。Provider只是把渲染工作完全交給子元件,它扮演的只是提供Context。

2、React-Redux

改進React的兩個方法:

  • 把一個元件拆分為容器元件和傻瓜元件,使用connect連線。
  • 使用React的Context來提供一個所有元件都可以直接訪問的Context,使用Provider實現。

mapStateToProps函式:把Store上的狀態轉化為內層傻瓜元件的props

mapDispatchToProps函式:把內層傻瓜元件中的使用者動作轉化為派送給Store的動作

六:Redux中介軟體

Redux的單向資料流是同步操作,驅動Redux流程的是action物件,每一個action物件被派發到Store上之後,同步的被分配給所有的reducer函式,每個reducer都是純函式,純函式不產生任何副作用,自然是完成資料操作之後立刻同步返回,reducer返回的結果又被同步的拿去更新Store上的狀態資料,更新狀態資料的操作會立刻被同步給監聽Store狀態改變的函式,從而引發作為檢視的React元件更新過程。

在Redux的單向資料流中,在action物件被reducer函式處理之前,是插入非同步功能的時機。在Redux架構下,一個action物件在通過store.dispatch派發,在呼叫reducer函式之前,會先經過一箇中介軟體的環節,這就是產生非同步操作的機會。

使用名為middlewares的陣列來儲存所有的中介軟體,如果需要匯入中介軟體放在middlewares陣列中就可以。

非同步action物件

如果沒有redux-thunk中介軟體的存在,這樣一個函式型別的action物件就被派發出來會一路傳送到各個reducer函式,有了redux-thunk中介軟體之後,這些action物件沒有機會觸及到reducer函式,在中介軟體一層被redux-thunk截獲。

redux-thunk的工作就是檢查action物件是不是函式,如果不是函式就放行,完成普通action物件的生命週期,而如果發現action物件就是函式,那就執行函式,並把Store的dispatch函式和getState函式作為引數傳遞到函式中去,處理過程到此為止,不會讓這個非同步action物件繼續往前派發到reducer函式。

非同步action最終還是要產生同步action派發才能對Redux系統產生影響;訪問伺服器的非同步action,無論成敗,都要通過派發action物件改變Redux Store上的狀態完結。

action物件被派發時,會讓React元件進入各自不同的三種狀態:

  • 非同步操作正在進行中
  • 非同步操作已經成功完成
  • 非同步操作已經失敗


相關文章