標籤:傳回值 script name com 架構 content bin 開始 ops
最近一個同事很急沒有做任何交接就請了陪產假,然後我來維護。說實在的我一開始是一臉懵逼的。因為MV*項目裡用的最多的還是Vue;React聽說也瞭解過,但畢竟不熟。。。
不過不管如何這也是工作;同事也恭喜同事當爸了,打心理為他感到高興!
代碼down下來後開始查看的時候文法基本上使用的都是CMD,ES6還有本文講的JSX,React組件。CMD,ES6這不難畢竟平常也經常用。但是JSX,React組件一開始就有點懵逼,
不過多看幾遍加百度Google就懂了。
(好像廢話有點多,好了,開始講重點....)
首先是JSX:
我一開始看的時候,咦,怎麼寫dom不需要引號嗎?後來才知道React發明了JSX利用html文法來建立虛擬dom。這同時也是React的核心之一。可以在記憶體中建立的虛擬DOM元素。React利用虛擬DOM來減少對實際DOM的操作從而提升效能。類似於真實的原生DOM,虛擬DOM也可以通過JavaScript來建立(React.createElement)
render(){ return React.createElement(‘div‘,null,‘content text‘) }
JSX本身就和XML文法類似,可以定義屬性以及子項目。唯一特殊的是可以用大括弧來加入;大括弧中的文法就是純JavaScript運算式,傳回值會賦予組件的對應屬性,因此可以使用任何JavaScript變數或者函數調用。同時大括弧中使用JavaScript運算式來返回需要展現的元素。
JSX中的事件
JSX採用駝峰寫法來描述事件名稱,大括弧中仍然是標準的JavaScript運算式,返回一個事件處理函數。在JSX中你不需要關心什麼時機去移除事件綁定,因為React會在對應的真實DOM節點移除時就自動解除了事件綁定。且採用事件代理的模式:在根節點document上為每種事件添加唯一的Listener,然後通過事件的target找到真實的觸發元素。這樣從觸發元素到頂層節點之間的所有節點如果有綁定這個事件,React都會觸發對應的事件處理函數。這就是所謂的React類比事件系統。儘管整個事件系統由React管理,但是其API和使用方法與原生事件一致。這種機制確保了跨瀏覽器的一致性:在所有瀏覽器(IE8及以上)都可以使用符合W3C標準的API,包括stopPropagation(),preventDefault()等等。對於事件的冒泡(bubble)和捕獲(capture)模式也都完全支援
<button onClick={this.checkAndSubmit.bind(this)}>Submit</button> 在JSX中使用樣式
在JSX中使用樣式和真實的樣式也很類似,通過style屬性來定義,但和真實DOM不同的是,屬性值不能是字串而必須為對象,例如:
<div style={{color: ‘#ff0000‘, fontSize: ‘14px‘}}>Hello World.</div>
這段JSX中的大括弧是雙的,有點奇怪,但實際上裡面的大括弧只是標準的JavaScript對象運算式,外面的大括弧是JSX的文法。所以,樣式你也可以先賦值給一個變數,然後傳進去,代碼會更易讀:
var style = { color: ‘#ff0000‘, fontSize: ‘14px‘};var node = <div style={style}>HelloWorld.</div>;
注意:在JSX中可以使用所有的的樣式,基本上屬性名稱的轉換規範就是將其寫成駝峰寫法,例如“background-color”變為“backgroundColor”, “font-size”變為“fontSize”,這和標準的JavaScript操作DOM樣式的API是一致的。
React自訂群組件
首先看一個React官方的demo:
class HelloWorld extends React.Component{ render() { return ( <p> Hello, <input type="text" placeholder="Your name here" />! It is {this.props.date.toTimeString()} {/*通過this.props.data擷取傳過來的資料*/} </p> ); }};setInterval(function() { React.render( <HelloWorld date={new Date()} />, document.getElementById(‘example‘) );}, 500); 組件的概念和生命週期
React使用組件來封裝介面模組,整個介面就是一個大組件,開發過程就是不斷最佳化和拆分介面組件、構造整個組件樹的過程。可以認為組件類似於其他架構中Widget(或Control)的概念,但又有所不同。React中的介面一切皆為組件,而Widget一般只是嵌入到介面中為完成某個功能的獨立模組。如,整個頁面是一個大的組件,然後再將其拆分成很多小的組件。組件機制加上JSX的文法,讓你在構造介面時就像有一套符合項目需求的HTML標記,介面定義變得非常直觀。
組件自身定義了一組props作為對外介面,每次props改變都能以整體重新整理頁面的思路去考慮介面展現邏輯。展示一個組件時只需要指定props作為XML節點的屬性。組件很少需要對外公開方法,唯一的互動途徑就是props。這使得使用組件就像使用函數一樣簡單,給定一個輸入,組件給定一個介面輸出。當給予的參數一定時,那麼輸出也是一定的。而傳統控制項通常提供很多方法讓你在外部改變控制項的狀態和行為,當控制項的狀態在不同情境不同邏輯中可以被隨意控制時,開發和調試也會變得複雜。
如果整個項目完全採用React,那麼介面上就只有一個組件根節點;如果局部使用React,那麼每個局部使用的部分都有一個根節點。在Render時,根節點由React.render函數去觸發:
React.render( <App />, document.getElementById(‘react-root‘));
而所有的子節點則都是通過父節點的render方法去構造的。每個組件都會有一個render方法,這個方法返回組件的執行個體,最終整個介面得到一個虛擬DOM樹,再由React以最高效的方式展現在介面上。
除了props之外,組件還有一個很重要的概念:state。組件規範中定義了setState方法,每次調用時都會更新群組件的狀態,觸發render方法。需要注意,render方法是被非同步呼叫的,這可以保證同步的多個setState方法只會觸發一次render,有利於提高效能。和props不同,state是組件的內部狀態,除了初始化時可能由props來決定,之後就完全由組件自身去維護。在組件的整個生命週期中,React強烈不推薦去修改自身的props,因為這會破壞UI和Model的一致性,props只能夠由使用者來決定。
對於自訂群組件,唯一必須實現的方法就是render();除此之外,還有一些方法會在組件生命週期中被調用,如所示:
圖中的方法幾乎已經包括了React的所有API,自訂群組件時根據需要在組件生命週期的不同階段實現不同的邏輯。除了必須的render方法之外,其它常用的方法包括:
componentDidMount: 在組件第一次render之後調用,這時組件對應的DOM節點已被加入到瀏覽器。在這個方法裡可以去實現一些初始化邏輯。
componentWillUnmount: 在DOM節點移除之後被調用,這裡可以做一些相關的清理工作。
shouldComponentUpdate: 這是一個和效能非常相關的方法,在每一次render方法之前被調用。它提供了一個機會讓你決定是否要對組件進行實際的render。
shouldComponentUpdate(nextProps, nextState) { return nextProps.id !== this.props.id;}
當此函數返回false時,組件就不會調用render方法從而避免了虛擬DOM的建立和記憶體中的Diff比較,從而有助於提高效能。當返回true時,則會進行正常的render的邏輯。
組件是React的核心,雖然功能很強大,但是其API和概念卻十分簡單,以至於你只要實現一個render方法就可以建立一個組件。這大大降低了React學習門檻。
參考及原文地址:http://www.infoq.com/cn/articles/react-jsx-and-component/
React的JSX文法及組件