相信不少新手朋友們對於React、Redux、React-Redux這三者之間的關係和區別確定有不少不解和疑惑。這裏咱們就來詳細的剖析一下它們吧。
react
React
:負責組件的UI界面渲染;
Redux
:數據處理中心;
React-Redux
:鏈接組件和數據中心,也就是把React和Redux聯繫起來。
es6
React主要就是用來實現UI界面的,是一個專一於view層的框架。對於一些小項目,若是數據的交互不是不少,徹底能夠只使用React就能很好的實現。
ajax
在傳統的頁面開發模式中,須要屢次的操做DOM來進行頁面的更新,咱們都知道對DOM的操做會形成極大的性能問題。而React的提出就是減小對DOM的操做來提高性能,也就是Virtual DOM。算法
Virtual DOM就至關於一個虛擬空間,React就是基於 Virtual DOM 來工做的。
redux
它的工做過程是:當有數據須要進行更新時,會先計算 Virtual DOM ,並和上一次的 Virtual DOM 作對比,獲得DOM結構的區別,而後只會將須要變化的部分批量的更新到真實的DOM上。
api
說到如何去計算Virtual DOM,在React裏面,用到的是react-diff算法。咱們都知道傳統的diff算法是經過循環遞歸對每一個節點進行依次對比,效率低下,算法複雜度達到了 O(n^3),其中 n 是樹中節點的總數。
性能優化
根據react diff策略:
bash
React 分別對 tree diff、component diff 以及 element diff 進行了算法優化:
架構
tree diff
:對樹進行分層比較,兩棵樹只會對同一層次的節點進行比較component diff
:element diff
:當節點處於同一層級時,React diff 提供了三種節點操做,分別爲:插入、移動、刪除。這是整個react diff算法的比較流程圖:
app
React總共有10個周期函數(render重複一次),這10個函數能夠知足咱們全部對組件操做的需求,利用的好能夠提升開發效率和組件性能。
1、組件在初始化時會觸發5個鉤子函數:
getDefaultProps()
設置默認的props,es6中用 static dufaultProps={}
設置組件的默認屬性。在整個生命週期只執行一次。
getInitialState()
在使用es6的class語法時是沒有這個鉤子函數的,能夠直接在constructor中定義this.state。此時能夠訪問this.props。
componentWillMount()
ajax數據的拉取操做,定時器的啓動。組件初始化時調用,之後組件更新不調用,整個生命週期只調用一次,此時能夠修改state。
render()
React最重要的步驟,建立虛擬dom,進行diff算法,更新dom樹都在此進行。此時就不能更改state了。
componentDidMount()
動畫的啓動,輸入框自動聚焦組件渲染以後調用,能夠經過this.getDOMNode()獲取和操做dom節點,只調用一次。
2、在更新時也會觸發5個鉤子函數:
componentWillReceivePorps(nextProps)
組件初始化時不調用,組件接受新的props時調用。無論父組件傳遞給子組件的props有沒有改變,都會觸發。
shouldComponentUpdate(nextProps, nextState)
React性能優化很是重要的一環。組件接受新的state或者props時調用,咱們能夠設置在此對比先後兩個props和state是否相同,若是相同則返回false阻止更新,由於相同的屬性狀態必定會生成相同的dom樹,這樣就不須要創造新的dom樹和舊的dom樹進行diff算法對比,節省大量性能,尤爲是在dom結構複雜的時候。不過調用this.forceUpdate會跳過此步驟。
componentWillUpdate(nextProps, nextState)
組件初始化時不調用,只有在組件將要更新時才調用,此時能夠修改state
render()
很少說
componentDidUpdate()
組件初始化時不調用,組件更新完成後調用,此時能夠獲取dom節點。
3、卸載鉤子函數
componentWillUnmount()
定時器的清除組件將要卸載時調用,一些事件監聽和定時器須要在此時清除。
Redux是一種架構模式,是由flux發展而來的。
Redux主要由三部分組成:store,reducer,action。
Redux的核心是store,它由Redux提供的 createStore(reducer, defaultState) 這個方法生成,生成三個方法,getState(),dispatch(),subscrible()。
reducer是一個純函數,它根據previousState和action計算出新的state。
reducer(previousState,action)
action本質上是一個JavaScript對象,其中必須包含一個type字段來表示將要執行的動做,其餘的字段均可以根據需求來自定義。
const ADD_TODO = 'ADD_TODO'
複製代碼
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
複製代碼
他們三者之間的交互,能夠由下圖歸納:
Redux 自己和React沒有關係,只是數據處理中心,是React-Redux讓他們聯繫在一塊兒。
React-rRedux提供兩個方法:connect和Provider。
connect鏈接React組件和Redux store。connect其實是一個高階函數,返回一個新的已與 Redux store 鏈接的組件類。
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
複製代碼
TodoList是 UI 組件,VisibleTodoList就是由 react-redux 經過connect方法自動生成的容器組件。
mapStateToProps
:從Redux狀態樹中提取須要的部分做爲props傳遞給當前的組件。mapDispatchToProps
:將須要綁定的響應事件(action)做爲props傳遞到組件上。Provider實現store的全局訪問,將store傳給每一個組件。
原理:使用React的context,context能夠實現跨組件之間的傳遞。
下圖闡述了它們三者之間的工做流程: