React元件在生命週期裡面大概有兩種情況,一種是初次渲染,一種是狀態更新導致再次渲染。我們們從元件生命週期的每一步可進行的操作的角度來了解一下。
初次渲染
- 建構函式,指定This,初始狀態,繫結函式(constructor)
constructor(props){
//指定This
super(props)
//設定初始化狀態
this.state={
value:'',
focus:false
}
//為元件上的函式繫結this
this.handleChange = this.handleChange.bind(this);
}複製程式碼
建構函式在元件初次渲染的時候只執行一次,建構函式裡面進行的操作大概有上述程式碼的三種操作。
2.元件安裝(componentWillMount)
void componentWillMount()複製程式碼
在元件掛載之前呼叫一次。在這個函式裡面你可以呼叫setState方法設定元件state,然後經過render函式渲染可以得到state被設定之後的效果。
3.元件生成DOM,必須JSX規則(render)
render(){
return(
<div className="FilterableProductTable">
<SearchBar value={this.state.value} handleChange={this.handleChange} handleFocus={this.handleFocus} handleOnblur={ this.handleOnblur}/>
<ProductTable data={this.props.JsonData} focus={this.state.focus} value={this.state.value} handleSelect={this.handleSelect}/>
</div>
);
}複製程式碼
這個 render 方法必須要返回一個 JSX 元素。
必須要用一個外層的 JSX 元素把所有內容包裹起來,返回並列多個 JSX 元素是不合法的.在這裡render函式只呼叫一次
4.查詢DOM或者請求資料(componentDidMount)
void componentDidMount()複製程式碼
在第一次渲染後呼叫,此時元件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。
如果你想和其他JavaScript框架一起使用,可以在這個方法中呼叫setTimeout, setInterval或者傳送AJAX請求等操作(防止異部操作阻塞UI)
元件的二次渲染
導致元件進行二次渲染的原因一般有三種
1.父元件的props發生更新
void componentWillReceiveProps(nextProps)複製程式碼
props是父元件傳遞給子元件的。當子元件接受到nextProps時,不管這個props與原來的是否相同都會執行該方法。
bool shouldComponentUpdate(nextProps, nextState)複製程式碼
shouldComponentUpdate
方法接收一個新的props和state,函式返回一個bool型別資料決定是否更新元件。如果返回false,則不進行更新。如果返回true,則進入下一環節。通常情況下為了優化,我們需要對新的props以及state和原來的資料作對比,如果發生變化。一般用immutable
,判斷如下
import React, { Component } from 'react';
import { is, fromJS } from 'immutable';
shouldComponentUpdate(nextProps, nextState) {
return !is(fromJS(this.props), fromJS(nextProps))|| !is(fromJS(this.state),fromJS(nextState))
}複製程式碼
當元件決定繼續更新時,會進入componentWillUpdate
方法
void componentWillUpdate(nextProps, nextState)複製程式碼
之後執行render函式更新DOM
ReactElement render()複製程式碼
執行完render函式之後執行componentDidUpdata
,
void componentDidUpdate()複製程式碼
除了首次render之後呼叫componentDidMount
,其它render結束之後都是呼叫componentDidUpdate
。
當元件需要被解除安裝的時候,呼叫 componentWillUnmount 方法
void componentWillUnmount()複製程式碼
一般在componentDidMount
裡面註冊的事件需要在這裡刪除。
2.呼叫this.forceUpdate更新(重複componentWillUpdate方法之後的操作)
當元件呼叫forceUpdata方法更新時,會進入componentWillUpdate
方法。直接跳過shouldComponentUpdta
void componentWillUpdate(nextProps, nextState)複製程式碼
之後執行render函式更新DOM
ReactElement render()複製程式碼
執行完render函式之後執行componentDidUpdata
,
void componentDidUpdate()複製程式碼
除了首次render之後呼叫componentDidMount
,其它render結束之後都是呼叫componentDidUpdate
。
當元件需要被解除安裝的時候,呼叫 componentWillUnmount 方法
void componentWillUnmount()複製程式碼
一般在componentDidMount
裡面註冊的事件需要在這裡刪除。
3.呼叫this.setState方法更新元件state,觸發元件更新
呼叫this.setState()方法更新元件state,首先會觸發shouldComponentUpdata(nextProps,nextState)
在方法判斷過後,決定是否更新。更新的操作和呼叫this.forceUpdate更新的操作是一樣的。
下面給大家一張元件的生命週期的圖,這張圖是我根據自己的理解以及日常操作用到的情況畫出來的。歡迎大家提出自己的見解,如有不正確的地方歡迎大家提出批評以及修改意見。謝謝。