? ? ? ? 要講React的生命周期的話,網(wǎng)上講的已經(jīng)很過(guò)了,不過(guò)大多數(shù)是講react單個(gè)組件的生命周期,理論上組件本質(zhì)是狀態(tài),生命周期大致分為三個(gè)階段,大致流程如下:
一、初始化階段
getDefaultProps:獲取實(shí)例的默認(rèn)屬性(即使沒有生成實(shí)例,組件的第一個(gè)實(shí)例被初始化createClass的時(shí)候調(diào)用,只調(diào)用一次)
?getInitialState:獲取每個(gè)實(shí)例的初始化狀態(tài)(每個(gè)實(shí)例自己維護(hù))
?componentWillMount:組件即將被裝載、渲染到頁(yè)面上,即組件掛載之前調(diào)用一次,如果在這個(gè)函數(shù)中調(diào)用setState,本次的render函數(shù)可以看到更新后的state,并且只渲染一次 render:組件在這里生成虛擬的DOM節(jié)點(diǎn)(只能訪問this.props和this.state,只有一個(gè)頂層組件,render返回值只能是一個(gè)組件,不允許修改狀態(tài)和DOM輸出)?
componentDidMount:在組件掛載之后調(diào)用一次,這個(gè)時(shí)候子組件也都掛載好了,可以在這里使用refs。組件真正在被裝載之后可以修改DOM
二、運(yùn)行中狀態(tài)
componentWillReceiveProps(nextProps):當(dāng)組件props改變的時(shí)候,組件將要接收到新的屬性的時(shí)候調(diào)用。props是父組件傳遞給子組件的,父組件發(fā)生render的時(shí)候子組件就會(huì)調(diào)用這個(gè)方法,不管props有沒有更新,也不管父子組件之間有沒有數(shù)據(jù)交換。
?shouldComponentUpdate(nextProps,nextState):當(dāng)組件數(shù)據(jù)(props)或者狀態(tài)(state)改變的時(shí)候調(diào)用,組件掛載之后,每次調(diào)用setState后都會(huì)調(diào)用shouldComponentUpdate判斷是否需要重新渲染組件。默認(rèn)返回true,需要重新render。在比較復(fù)雜的應(yīng)用里,有一些數(shù)據(jù)的改變并不影響界面顯示,可以在這里做判斷,優(yōu)化渲染效率。?
componentWillUpdate(nextProps,nextState):這個(gè)是shouldComponentUpdate方法返回true的時(shí)候或者調(diào)用forceUpdate之后調(diào)用。這時(shí)候不能修改屬性和狀態(tài) render:只能訪問this.props和this.state,只有一個(gè)頂層組件,render返回值只能是一個(gè)組件,不允許修改狀態(tài)和DOM輸出
componentDidUpdate:除了首次render之后調(diào)用componentDidMount,其他render結(jié)束之后都是調(diào)用componentDidUpdate
三、銷毀階段
componentWillUnmount:開發(fā)者需要來(lái)銷毀(組件真正刪除之前調(diào)用,比如銷毀計(jì)時(shí)器和事件監(jiān)聽器)
下面是從官網(wǎng)上找到的一張流程圖,把上面的步驟描述的非常詳細(xì)了。

對(duì)于一個(gè)工程來(lái)說(shuō),一般是多個(gè)組件組成的組件樹,因此弄清楚組件嵌套在一起的組件樹的生命周期,無(wú)論是對(duì)于項(xiàng)目?jī)?yōu)化還是對(duì)于項(xiàng)目的運(yùn)行過(guò)程的把控都是很重要的。下面研究一下,一個(gè)示例
//父組件
class Parent extends PureComponent {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? console.log('Parent constructor');
? ? }
? ? componentWillMount() {
? ? ? ? console.log('Parent componentWillMount');
? ? }
? ? render() {
? ? ? ? console.log('RootContainer render');
? ? ? ? return (
? ? ? ? ? ? <div className="root">
? ? ? ? ? ? ? ? <h3>This is Parent</h3>
? ? ? ? ? ? ? ? <Child/>
? ? ? ? ? ? </div>
? ? ? ? );
? ? }
? ? componentDidMount() {
? ? ? ? console.log('Parent componentDidMount');
? ? }
? ? componentWillUnmount() {
? ? ? ? console.log('Parent componentWillUnmount');
? ? }
? ? componentWillReceiveProps(nextProps) {
? ? ? ? console.log('Parent componentWillReceiveProps(nextProps)');
? ? }
? ? componentWillUpdate(nextProps, nextState) {
? ? ? ? console.log('Parent componentWillUpdate(nextProps, nextState)');
? ? }
? ? shouldComponentUpdate(nextProps, nextState) {
? ? ? ? console.log('Parent shouldComponentUpdate(nextProps, nextState)');
? ? ? ? return true;
? ? }
? ? componentDidUpdate(prevProps, prevState) {
? ? ? ? console.log('Parent componentDidUpdate(prevProps, prevState)');
? ? }
}
//子組件
class Child extends PureComponent {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? console.log('Child constructor');
? ? }
? ? componentWillMount() {
? ? ? ? console.log('Child componentWillMount');
? ? }
? ? render() {
? ? ? ? console.log('Child render');
? ? ? ? return (
? ? ? ? ? ? <div className="child">
? ? ? ? ? ? ? ? <h4>I am a Child</h4>
? ? ? ? ? ? </div>
? ? ? ? );
? ? }
? ? componentDidMount() {
? ? ? ? console.log('Child componentDidMount');
? ? }
? ? componentWillUnmount() {
? ? ? ? console.log('Child componentWillUnmount');
? ? }
? ? componentWillReceiveProps(nextProps) {
? ? ? ? console.log('Child componentWillReceiveProps(nextProps)');
? ? }
? ? shouldComponentUpdate(nextProps, nextState) {
? ? ? ? console.log('ChildView shouldComponentUpdate(nextProps, nextState)');
? ? ? ? return true;
? ? }
? ? componentWillUpdate(nextProps, nextState) {
? ? ? ? console.log('Child componentWillUpdate(nextProps, nextState)');
? ? }
? ? componentDidUpdate(prevProps, prevState) {
? ? ? ? console.log('Child componetDidUpdate(prevProps, prevState)');
? ? }
}
運(yùn)行后結(jié)果如下:
Parent constructor
Parent componentWillMount
Parent render
Child constructor
Child componentWillMount
Child render
Child componentDidMount
Parent componentDidMount
此時(shí)可以分析出,當(dāng)父組建?render?時(shí)遇到子組件,然后進(jìn)入子組件的生命周期,當(dāng)執(zhí)行完子組件生命周期中的componentDidMount?時(shí)會(huì)回到父組建繼續(xù)執(zhí)行父組建未完成的生命周期。
由上面父子嵌套組件的生命周期流程,可以推斷繼續(xù)驗(yàn)證多級(jí)組件嵌套的流程,