React 生命週期方法執行順序
-
呼叫super的原因:在ES6中,在子類的
constructor
中必須先呼叫super
才能引用this
-
super(props)
的目的:在constructor
中可以使用this.props
對於一個包含著生命週期的元件,有以下可選的生命週期方法:
-
componentWillMount()
僅在render()
方法前被呼叫一次,如果在該方法中呼叫了setState
方法去改變元件的狀態值,那麼呼叫render()
後,將會直接看到改變過了的狀態值,並且不論狀態值怎麼改變,componentWillMount()
都不會再被呼叫 -
componentDidMount()
僅在render()
方法後被立即呼叫一次(客戶端),相對於父元件而言,該方法在子元件中會先被呼叫。如果需要使用一些JaveScript框架或者類似於setInterval()
這樣的方法,建議在該方法內使用。 -
ShouldComponentUpdate(object nextProps, object nextState)
在初始渲染呼叫render()方法時不會被呼叫,後面在接受到新的state或者props時,在render()方法前被呼叫。為防止一些潛在的bug,該方法預設總是返回true。如果你確定state及props改變後不需要渲染元件,那麼也可以指定返回false,需要注意的是,這樣的結果會導致後面的render()、componentWillUpdate()、componentDidUpdate()都不會被呼叫。 -
componentWillReceiveProps(object nextProps)
在初始渲染呼叫render()
方法時不會被呼叫,當接收到一個新的props時,該方法被呼叫。我們都知道,如果改變一個狀態的值,則會觸發render()
方法,所以可以在這個方法裡呼叫setState()
方法去改變一個狀態的值,當該方法接收到新的props
時,setState()
就可以避免一次額外的render()
了。
在這個方法裡,尤其需要注意一點,就是接收到新的props
一定會觸發render()
方法,但是render()
方法被觸發不一定是因為接收到了新的props
(具體請戳這裡)。如下:class Demo extends React.Component { componentWillReceiveProps(nextProps) { console.log('componentWillReceiveProps is invoked', nextProps.val.name) } render() { return ( <div>{this.state.value}</div> ) } } var data = { name: 'zhou xiao cheng' } ReactDOM.render(<Demo val={data} />, document.getElementById('app')) ReactDOM.render(<Demo val={data} />, document.getElementById('app')) ReactDOM.render(<Demo val={data} />, document.getElementById('app'))
在上面的程式碼中,
props
沒有發生改變,但render()
方法卻被呼叫了兩次。 -
componentWillUpdate(object nextProps, object nextState)
在初始渲染呼叫render()
方法時不會被呼叫,當接收到新的props及state時,在render()
方法之前被呼叫。 -
componentDidUpdate(object prevProps, object prevState)
在初始渲染呼叫render()
方法時不會被呼叫,當元件更新被重新整理到DOM之後被立即呼叫。 -
componentWillUnmount()
在元件從DOM上解除安裝前被呼叫,在這個方法裡面,我們主要是完成一些清除操作,比如說清除掉一些過時了的定時器等。
元件規範介紹
除了上面的7個可選的生命週期方法,我們可以將剩下的一些方法稱之為元件規範。接下來,我們將會對一些較為常用的元件規範進行介紹。
-
render()
對於一個元件而言,render()
方法是必須的,通常,在這個方法裡面,我們都會返回一個元素(如:<div></div>
),但同樣也可以返回false
或null
,這意味著我們沒有任何東西需要渲染。 -
getInitialState()
在ES6的語法中,這個方法可以寫成下面這樣(將其寫在建構函式中,this.state
的值就是狀態初始值),其效果是一樣的:class Demo extends React.Component { constructor() { super() this.state = { key: value } }
-
getDefaultProps()
ES6的語法中,寫法如下:Demo.defaultProps = {key: value}
ES7中,還可以寫成這樣(但需要配合Babel轉換器進行使用):
class Demo extends React.Component { static defaultProps = { key: value } }
-
propTypes
ES6的語法中,寫法如下(想了解更多propTypes請戳官方propTypes介紹):Demo.propTypes = { requiredFunc: React.PropTypes.func.isRequired }
同樣,在ES7中,可以寫成下面這樣:
class Demo extends React.Component { static propTypes = { requiredFunc: React.PropTypes.func.isRequired } }
-
static
ES6語法中,static關鍵字則允許我們定義一個在元件類上能夠呼叫的靜態方法和屬性:class Demo extends React.Component { static method = function(){ //doSomething } static propTypes = { requiredFunc: React.PropTypes.func.isRequired } }
//呼叫靜態方法 Demo.method() //呼叫屬性 Demo.propTypes
呼叫順序及次數
如果你能理解上面所敘述的,那麼,就不難得出下面的結論啦~~~
getDefaultProps()
,呼叫1次getInitialState()
,呼叫1次componentWillMount()
,呼叫1次render()
,呼叫>=1次componentDidMount()
:僅客戶端,呼叫1次componentWillReceiveProps(object nextProps)
,呼叫>=0次ShouldComponentUpdate(object nextProps, object nextState)
,呼叫>=0次componentWillUpdate(object nextProps, object nextState)
,呼叫>=0次render()
,呼叫>=1次componentDidUpdate(object prevProps, object prevState)
,呼叫>=0次componentWillUnmount()
,呼叫1次
好了,這次就寫到這了,望與各君共勉。