也能夠在這裏看:http://leozdgao.me/liao-jie-ge-reactzu-jian/html
最近React,這個專一View層的庫格外火熱,我我的已經探索了一段時間,原本一直想寫一些文字,總結下React應用開發和webpack構建工具的經驗。不過懶癌復發,一直沒動筆。前段時間給團隊安利這個庫,如今要開始用它寫項目了,因此本身挖的坑要填上,就開始寫一些基本的東西,就先從介紹React組件的基礎開始。react
標題叫「一個簡單的組件」,因而先來看下官方網站上一個叫作「A Simple Component」的例子來感覺下:webpack
var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div> } }) React.render(<HelloMessage name="John" />, mountNode)
好的,經過React提供的工廠方法,咱們建立了一個組件,在這裏,咱們認爲createClass
建立了一張blueprint,而經過jsx語法建立的<HelloMessage name="John" />
則返回一個ReactElement
對象來具體地告訴React要如何渲染組件(由於除了blueprint之外還須要一些外部狀態的傳入),這等同於調用React.createElement(HelloMessage, { name: 'John' }, 'Hello ', this.props.name)
。web
以後,React就能夠根據ReactElement
對象,把組件掛載到頁面的某個節點上去,也就是React.render
方法在作的事情,這個方法返回一個組件的實例,同時也意味着你能夠在已有項目中的一小部分嘗試React。api
下面來具體介紹下。瀏覽器
上面的例子裏看着像是把HTML寫在了Js裏,其實是經過一種更加清晰易讀且易維護的語法JSX來建立ReactElement
對象。對React來講JSX是可選的,若是真的不喜歡也能夠用React.createElement
這個api。babel
固然有JSX語法的js文件是不能直接在瀏覽器中運行的,咱們能夠用官方的JSXTransformer
或者是babel
來轉換。函數
須要注意的是class
和for
這兩個HTML屬性,因爲組件的屬性實際是以對象形式傳遞的,好比上面的{ name: 'John' }
,另外js不容許關鍵字做爲屬性名,因此須要分別用className
和htmlFor
代替。工具
建立組件的時候須要給React.createClass
提供一個對象,這個對象必須包含一個render
方法和若干可選的生命週期方法。性能
要注意的是咱們須要保證render
函數是純函數,即一樣的輸入始終返回相同的輸出,而且執行過程當中沒有反作用(和DOM交互或者發Ajax請求)。但一個組件要和DOM交互或者發Ajax請求需求是很正常的,那麼就要用到其餘生命週期方法了。
除此以外,更重要的部分是,讓一個組件能夠工做除了有blueprint外,還須要組件狀態。對於一個React組件來講,分爲不可變狀態this.props
和可變狀態this.states
。
咱們能夠經過this.props
決定一個組件內的部分呈現內容,好比上例中咱們但願呈現的名字是John,且不會改變。然而對於一個DropDownList
而言,僅在點擊它時,一個下拉列表纔會顯示出來,那麼咱們認爲這個下拉列表是否顯示就是一個可變狀態。
說到可變狀態,那麼要這麼變?React並不但願咱們直接修改this.states
,咱們須要使用this.setState
的方式修改狀態,由於每次調用this.setState
,render
方法都會被再次調用,同時也會調用一些相關的生命週期函數。this.setState
接受一個對象做爲新狀態的patch,也就是說這個對象不會覆蓋現有的this.states
,而是一個相似extend的行爲。
咱們也能夠提供一些默認狀態:
getDefaultProps () { return { name: 'defaultName' }; }, getInitialState: function() { return { listShowed: false }; },
其中getDefaultProps
僅會被調用一次,這裏的意思是不管你會建立多少個ReactElement
,這個函數都只執行一次,以後的默認props
都會直接使用改函數的返回值。
這裏須要提一下React提供以ES6的方式建立組件,有意思的是ES6的版本用的是React.Component
,在語意上比createClass
更加明確。getDefaultProps
和getInitialState
在ES6的版本中有些不太同樣,相對與getDefaultProps
,ES6將默認屬性對象做爲了構造函數的一個屬性,而getInitialState
則變成了在其構造器函數中給this.state
賦值,來看一個栗子:
class HelloMessage extends React.Component { constructor (props) { this.super(props) this.state = { } // 初始化狀態 } render () { return <div>Hello {this.props.name}</div> } } HelloMessage.defaultProps = { name: 'defaultName' }
以前的部分一直有提到生命週期函數,下面就來介紹下:
componentWillMount
會在組件即將被掛載時調用,此時this.refs
對象爲空對象。若是在該函數中使用this.setState
,那麼會更新this.states
對象,而render
依然只會調用一次,至關因而能夠覆蓋getInitialState
返回的對象,雖然我以爲這沒什麼意義。
componentDidMount
是很是經常使用的生命週期方法,僅當組件被掛載後調用一次,這意味着能夠在這個函數中進行一些DOM操做等,好比但願組件中的一個textbox能夠再掛載後自動獲取焦點:
componentDidMount () { const textbox = React.findDOMNode(this.refs.text) if (this.props.autoFocus) textbox.focus() }
componentWillReceiveProps
在將要接受新的props
時被調用,不是說props
是不可變狀態嗎?狀況一般是這樣的,當一個父組件包含了一個子組件,子組件的一個props
的值是父組件的states
的值,那麼當父組件可變狀態改變時,子組件的props
也更新了,因而調用了這個函數。
componentWillReceiveProps (nextProps) { if (this.props.disabled !== nextProps.disabled) { // disabled這個屬性改變了 } }
這個生命週期函數componentWillReceiveProps
提供了更新states
的機會,能夠調用this.setState
,也是惟一能夠在組件更新週期中調用this.setState
的函數。
shouldComponentUpdate
是在更新前根據該函數的返回值決定是否進行此次更新。
shouldComponentUpdate (nextProps, nextState) { // 比較props或者states,返回true則更新照常,返回false則取消更新,且不會調用下面的兩個生命週期函數 }
考慮這種狀況:父組件有子組件A和子組件B,當父組件調用this.setState
更新一個做爲子組件A屬性的state
時,render
方法被再次調用,此時組件A和組件B同時被更新,其實真正改變的只有組件A,但組件B也同時被要求更新了,這是沒有必要的,因而shouldComponentUpdate
就顯的有用了,在該函數體內比較props
或是states
,若是沒有改變就取消這個更新,這對性能上算是一個提高。
但若是是複雜對象的比較就比較麻煩了,由於咱們沒法經過===
來判斷兩個對象的鍵值是否都相等,因而咱們就但願咱們的對象是不可變的(immutable)。這裏再也不展開了,你們能夠先自行探索,以後再寫這個部分的文字,並介紹immutable.js
componentWillUpdate
在組件被更新前調用一次,能夠用來作一些更新前的準備工做,舉個栗子:
componentWillUpdate (nextProps, nextState) { if (!this.props.isShowed && nextProps.isShowed) { // 好比下拉菜單此時變的顯示了,能夠對此監聽一些事件什麼的 } if (this.props.isShowed && !nextProps.isShowed) { // 好比下拉菜單隱藏了,能夠在這裏取消事件監聽 } }
(組件更新前事情還蠻多的...)
componentDidUpdate
在組件更新完成後調用,能夠考慮在這個函數中執行一些DOM操做什麼的。
注意:絕對不要在componentWillUpdate
和componentDidUpdate
中調用this.setState
方法,不然將致使無限循環調用。
componentWillUnmount
會在組件即將從掛載點移去時調用,此方法專門用來『擦屁股』,好比去除即將被銷燬的DOM節點的引用,或者是清除計時器,取消監聽的時間等等。
好了,正文結束,這一篇介紹了React比較基礎的部分,但願對你們有幫助,以後還會有一些更有針對性的部分。如文章中內容有誤,還請指正。