標籤:
本文是我學習react的階段性小結,如果看官你是react資深玩家,那麼還請就此打住移步他處,如果你想給一些建議和指導,那麼還請輕拍~
目前團隊內對react的使用非常普遍,之前對react使用不多,正好我目前在做的項目也在使用react+redux,藉著這個機會系統的學習下react+redux。
react是什麼
react是一個JavaScript類庫,通過react,我們可以構建可組合的UI,也就是說,我們可以通過重用組件來組合出我們的UI。可以說react的核心便是組件,目的就是重用和組合。
react解決什麼問題
官網有這樣一句話.
We built React to solve one problem: building large applications with data that changes over time.
我們知道,隨著應用規模的不斷擴大,UI背後的資料模型越來越複雜,商務邏輯也不可避免的變得越來越複雜,以至於複雜到僅僅是修複一個簡單的問題我們就需要投入大量的時間和精力。
現有的很多前端架構都在致力於解決這樣的問題,基本思想都是基於MV*的模式,這裡有一篇文章詳細介紹了各種MV*模式的原理和優缺點。
那麼,react是如何解決這個問題的呢?
react聚焦於組件。react理解的組件實際上就是一個狀態機器。當組件處於某個狀態時,就輸出這個狀態對應的介面。在React中,我們只需要簡單的去更新某個組件的狀態,然後輸出基於新狀態的整個介面。React負責以最高效的方式去比較兩個介面並更新DOM樹。至於如何對組件之外的資料進行管理,react提出了flux方案。
react點點點生命週期
前面我們知道,react組件是一個狀態機器,以狀態為輸入,以介面為輸出。在不同狀態切換之間,react提供了一系列的生命週期方法,大致可以分為如下三類:
執行個體化時期
react組件在執行個體化時會依次調用如下組件方法:
- getDefaultProps
- getInitialState
- componentWillMount
- render
- componentDidMount
存在期
當react組件被執行個體化後,使用者的一些操作會導致組件狀態的更新,此時如下方法將依次被調用:
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
銷毀時期
在組件銷毀的時候,會調用如下組件方法:
這裡有一段簡單的測試代碼:
var ChildComponent = React.createClass({ render: function () { console.log("call render"); return ( <div> {this.props.data} </div> ); }, componentWillReceiveProps: function () { console.log("call componentWillReceiveProps"); }, shouldComponentUpdate: function () { console.log("call shouldComponentUpdate"); return true; }, componentWillUpdate: function () { console.log("call componentWillUpdate"); }, componentDidUpdate: function () { console.log("call componentDidUpdate"); }, componentWillUnmount: function () { console.log("call componentWillUnmount"); }});var MyComponent = React.createClass( { getDefaultProps: function () { // console.log("call getDefaultProps"); return { className: "test" }; }, getInitialState: function () { // console.log("call getInitialState"); // console.log("log prop: ", this.props); return { text: "something" }; }, componentWillMount: function () { console.log("call componentWillMount"); }, componentDidMount: function () { console.log("call componentDidMount"); }, render: function () { console.log("call render"); var child; if (this.state.text === "after click") { child = null; } else { child = <ChildComponent data={this.state.text} />; } return ( <div className={this.props.className} onClick={this.handleClick}> {child} </div> ); }, handleClick: function () { this.setState({ text: "after click" }); }});ReactDOM.render( <MyComponent />, document.getElementById("content"));
常用API
關於API的部分,官網已經給了詳盡的說明,此處略去。
JSX
JSX是react的核心組件之一。react堅信標籤和產生它的代碼是緊密相連的,如果展示邏輯非常複雜(事實上大多數情況下都是),那麼通過範本語言來實現這些邏輯會產生大量代碼,於是react做了一個非常簡單、可選類似HTML文法 ,通過函數調用即可產生模板的編譯器,稱為JSX。
通過JSX,我們可以用HTML的文法建立JavaScript對象。比如,為了在React中產生一個連結,通過純JavaScript可以這麼寫:
React.createElement(‘a‘, {href: ‘http://facebook.github.io/react/‘}, ‘Hello React!‘)
通過JSX這就變成了:
<a href="http://facebook.github.io/react/">Hello React!</a>
我們發現通過JSX,代碼會更加簡潔和易讀,使用起來也更加方便。
更過關於JSX的內容請參考官方文檔.
組合可重用的組件
前面我們知道,react的核心就是組件,目的就是重用和組合。那麼我們如何才能做到組件可重用和組合呢?
首先說說組合。
組合描述的是一種從屬關係,在物件導向編程中被描述為HAS-A的關係。
在react中,我們通過如下的代碼實現組合:
<Parent><Child data={this.props.childData} /></Parent>
在這個例子中,Parent中有一個Child的執行個體,Parent是擁有著。在組件中,組件不能改變自身的props,組件的props始終與組件的擁有著設定的保持一致。
這裡就有一個非常有趣的事情。組件的props永遠來自於組件的擁有者(預設的除外),組件的擁有者可以通過它的props 或state計算出一些值,並把這些值綁定到它們擁有的組件的props上,即在react中,資料就通過props的方式從組件的擁有者單向的流向了組件。
再說說可重用。
可重用,第一感覺就是有一層抽象含義在其中。我們從若干相似的組件中抽象出一層介面,實現公用的組件。換句話說,我們把一些頁面上通用的設計項目(按鈕、表單等)拆分成介面設計良好的可複用組件。每一個組件經過良好的測試和封裝,那麼在下次開發相似的頁面的時候,可以寫更少的代碼,也意味著更高的開發效率和更高的品質。
更多關於組件組合和可重用的說明,請參考複合組件和可重用組件。
react學習小結(生命週期- 執行個體化時期 - 存在期- 銷毀時期)