標籤:
知道這個架構有一段時間了,可是項目中沒有用到,也懶得整理,最近兩天比較清閑,又想起了它。好了,廢話不多說了,都是乾貨。
- react是個什麼架構?
- 為什麼用react?
- react 的原理
- react有什麼特點?
- 文法 & 幾個小例子
react的一些總結
react是個什麼架構?
React 是一個 Facebook 和 Instagram 用來建立使用者介面的 JavaScript 庫。
很多人認為 React 是 mvc 中的 V(視圖),它可以與其他的架構共存;
react 的原理
在Web開發中,我們總需要將變化的資料即時反應到UI上,這時就需要對DOM進行操作。而 複雜或頻繁的DOM操作通常是效能瓶頸產生的原因 (如何進行高效能的複雜DOM操作通常是衡量一個前端開發人員技能的重要指標)。React為此引入了 虛擬DOM(Virtual DOM) 的機制:在瀏覽器端用Javascript實現了一套DOM API。基於React進行開發時所有的DOM構造都是通過虛擬DOM進行,每當資料變化時,React都會重新構建整個DOM樹,然後React將當前整個DOM樹和上一次的DOM樹進行對比,得到DOM結構的區別,然後僅僅將需要變化的部分進行實際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的重新整理,在一個事件迴圈(Event Loop)內的兩次資料變化會被合并,例如你連續的先將節點內容從A變成B,然後又從B變成A,React會認為UI不發生任何變化,而如果通過手動控制,這種邏輯通常是極其複雜的。儘管每一次都需要構造完整的虛擬DOM樹,但是因為虛擬DOM是記憶體資料,效能是極高的,而對實際DOM進行操作的僅僅是Diff部分,因而能達到提高效能的目的。這樣,在保證效能的同時,開發人員將不再需要關注某個資料的變化如何更新到一個或多個具體的DOM元素,而只需要關心在任意一個資料狀態下,整個介面是如何Render的。
如果你像在90年代那樣寫過伺服器端Render的純Web頁面那麼應該知道,伺服器端所要做的就是根據資料Render出HTML送到瀏覽器端。如果這時因為使用者的一個點擊需要改變某個狀態文字,那麼也是通過重新整理整個頁面來完成的。伺服器端並不需要知道是哪一小段HTML發生了變化,而只需要根據資料重新整理整個頁面。換句話說,任何UI的變化都是通過整體重新整理來完成的。而React將這種開發模式以高效能的方式帶到了前端,每做一點介面的更新,你都可以認為重新整理了整個頁面。至於如何進行局部更新以保證效能,則是React架構要完成的事情。
借用Facebook介紹React的視頻中聊天應用的例子,當一條新的訊息過來時,傳統開發的思路如,你的開發過程需要知道哪條資料過來了,如何將新的DOM結點添加到當前DOM樹上;而基於React的開發思路如,你永遠只需要關心資料整體,兩次資料之間的UI如何變化,則完全交給架構去做。可以看到,使用React大大降低了邏輯複雜性,意味著開發難度降低,可能產生Bug的機會也更少。
為什麼用react?
react為瞭解決:隨著時間資料不斷變化的大規模應用程式。主要採用下面的思想:
僅當表現當某一個時間點的應用程式長什麼樣子,然而當底層資料發生變化,視圖資料自動更新;
資料變化,只是更新變化的部分(這是react的特別之處,下面會講到)
react有什麼特點?
- 有虛擬dom樹,每次資料更新會對比更改的資料,只做diff的更新;
- 事件迴圈內的兩次資料變化會被合并,列如,資料從A改成B,然後從B改成A,react會認為沒有發生任何變化;
- react推薦以組件化的方式去重新思考構建UI,主要考慮組件間的分離 ;
文法 & 幾個小例子
好吧,先從最熟悉的hello world
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script src="build/react.js"></script> 5 <script src="build/JSXTransformer.js"></script> 6 </head> 7 <body> 8 <div id="container"></div> 9 <script type="text/jsx">10 // ** Our code goes here! **11 </script>12 </body>13 </html>
這邊主要引入2個js,分別是react.js 和 JSXTransformer.js,他們需要首先載入,其中JSXTransformer.js是將jsx轉換成javascript文法的。這一步很耗時間,實際應用的時候,應該放到伺服器上完成。
下面我們看下react的基本方法
React.render是React最基本的方法,是將jsx轉換成html ,並且插入到DOM
1 React.render(2 <h1>Hello, world!</h1>,3 document.getElementById(‘container‘)4 );
這裡需要注意的是,react並不依賴jQuery,當然我們可以使用jQuery,但是render裡面第二個參數必須使用JavaScript原生的getElementByID方法,不能使用jQuery來選取DOM節點。
到這裡我們已經邁入了React的大門。
下面說下jsx的文法
JSX 是一個看起來很像 XML 的 JavaScript 文法擴充。React 可以用來做簡單的 JSX 句法轉換。
一定要使用JSX嗎?
這個不一定,你不需要為了 React 使用 JSX,可以直接使用純粹的 JS。但我們更建議使用 JSX , 因為它能定義簡潔且我們熟知的包含屬性的樹狀結構文法。
對於非專職開發人員(比如設計師)同樣比較熟悉。XML 有固定的標籤開啟和閉合。這能讓複雜的樹更易於閱讀,優於方法調用和對象字面量的形式。
它沒有修改 JavaScript 語義。
再來個稍微複雜些的例子,做個搜尋功能
React是基於組件化的開發,那麼組件化開發最大的優點是什嗎?毫無疑問,當然是複用。
搜尋
首先搜尋肯定是要有個search的文字框&&搜尋按鈕
var Search = React.createClass({ render: function() { return ( <div> {this.props.searchType}:<input type="text" /> <button>Search</button> </div> ); } });
後面根據不同的內容去搜尋(title,content)
1 var Page = React.createClass({ 2 render: function() { 3 return ( 4 <div> 5 <h1>Welcome!</h1> 6 <Search searchType="Title" /> 7 <Search searchType="Content" /> 8 </div> 9 );10 }11 });
最後render渲染添加到DOM
1 React.render(2 <Page />,3 document.getElementById(‘container‘)4 );
注意標紅處
1、擷取屬性的值用的是this.props.屬性名稱
2、建立的組件名稱首字母必須大寫。
狀態切換改變(組件其實是狀態機器State
)
var InputState = React.createClass({ getInitialState: function() { return {enable: false}; }, handleClick: function(event) { this.setState({enable: !this.state.enable}); }, render: function() { return ( <p> <input type="text" disabled={this.state.enable} /> <button onClick={this.handleClick}>Change State</button> </p> ); } }); React.render( <InputState />, document.getElementById(‘container‘) );
我們又使用到了一個方法getInitialState,這個函數在組件初始化的時候執行,必需返回NULL或者一個對象。這裡我們可以通過this.state.屬性名稱來訪問屬性值,這裡我們將enable這個值跟input的disabled綁定,當要修改這個屬性值時,要使用setState方法。我們聲明handleClick方法,來綁定到button上面,實現改變state.enable的值.
1、getInitialState函數必須有傳回值,可以是NULL或者一個對象。2、訪問state的方法是this.state.屬性名稱。3、變數用{}包裹,不需要再加雙引號。4、組件的生命週期
組件的生命週期分成三個狀態:
- Mounting:已插入真實 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真實 DOM
React 為每個狀態都提供了兩種處理函數,will 函數在進入狀態之前調用,did 函數在進入狀態之後調用,三種狀態共計五種處理函數。
- componentWillMount()
- componentDidMount()
- componentWillUpdate(object nextProps, object nextState)
- componentDidUpdate(object prevProps, object prevState)
- componentWillUnmount()
此外,React 還提供兩種特殊狀態的處理函數。
- componentWillReceiveProps(object nextProps):已載入組件收到新的參數時調用
- shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調用
react的一些總結
1、ReactJs是基於組件化的開發,所以最終你的頁面應該是由若干個小工具組成的大組件。
2、可以通過屬性,將值傳遞到組件內部,同理也可以通過屬性將內部的結果傳遞到父級組件(留給大家研究);要對某些值的變化做DOM操作的,要把這些值放到state中。
3、為組件添加外部css樣式時,類名應該寫成className而不是class;添加內部樣式時,應該是style={{opacity: this.state.opacity}}而不是style="opacity:{this.state.opacity};"。
4、組件名稱首字母必須大寫。
5、變數名用{}包裹,且不能加雙引號。
參考文檔:http://www.tuicool.com/articles/ii6Nn2
初探react