React 生命周期
2.static getDerivedStateFromProps(props,state)
1.static getDerivedStateFromProps(props,state)
2.shouldComponentUpdate(nextProps, nextState)
3.componentWillUpdata(nextProps, nextState)
2.shouldComponentUpdate(nextProps,nextState)
3.componentWillUpdate(nextProps,nextState)
在React中,每個組件提供了生命周期鉤子函數(shù)去響應(yīng)組件在不同時刻應(yīng)該做的和可以做的事情.組件的掛載>數(shù)據(jù)更新階段>卸載階段
由于React 16版本中對生命周期有所更改,所以這里介紹新老版本,現(xiàn)在一般不建議使用React15版本的,會報安全性警告
React將組件渲染 > 構(gòu)造DOM > 展示到頁面的過程稱為組件的掛載.
constructor()是ES6中類的默認(rèn)方法,通過new命令生成對象實例時自動調(diào)用該方法.其中的super()是class方法中的繼承,它是使用extends關(guān)鍵字來實現(xiàn)的.子類必須在constructor()中調(diào)用super()方法,否則新建實例會報錯.如果沒有用到constructor(),React會默認(rèn)添加一個空的constructor()`
constructor()用來做一些組件初始化的工作,比如定義this.state的初始內(nèi)容,繼承父類獲取props
classBaseWorldextendsReact.Component{constructor(props){super(props);this.state={name:'liuqiao'};}render(){console.log(this.props);return(<div>{this.state.name}</div>);}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2.static getDerivedStateFromProps(props,state)
組件在裝載的時候,也就是組件在構(gòu)建之后(虛擬DOM之后,實際DOM掛載之前),每次獲取新的props或state之后,當(dāng)props更改時觸發(fā),然后返回的對象將會與當(dāng)前的狀態(tài)合并,作為新的state,返回null則說明不需要更新state.
staticgetDerivedStateFromProps(){console.log('getDerivedStateFromProps');returnnull;}
1
2
3
4
第一次的初始化組件以及后續(xù)的更新過程中(包括自身狀態(tài)更新以及父傳子)都會觸發(fā)此生命周期. 一般不怎么使用這個鉤子函數(shù)
非常重要的鉤子函數(shù).React最重要的步驟,創(chuàng)建虛擬dom,進(jìn)行diff算法,更新dom樹都會在此進(jìn)行.
render(){console.log('render');return(<div></div>);}
1
2
3
4
5
6
7
組件渲染之后,只調(diào)用一次,非常重要:表示dom準(zhǔn)備就緒,動態(tài)數(shù)據(jù)請求已經(jīng)初始化完成
componentDidMount(){console.log('----componentDidMount');// 開啟長連接// 開定時器// 調(diào)接口}
1
2
3
4
5
6
1.static getDerivedStateFromProps(props,state)
只要props或state有更新,就會觸發(fā)這個鉤子函數(shù),不常用
2.shouldComponentUpdate(nextProps, nextState)
用于判斷組件是否需要更新.也就是相當(dāng)于diff運算的開關(guān),一般我們會在此鉤子函數(shù)中進(jìn)行相關(guān)的性能優(yōu)化,比如我們設(shè)置在此對比前后兩個props和states是否相同,如果相同則返回false阻止更新.因為相同的屬性狀態(tài)一定會生成相同的dom樹,這樣就不需要創(chuàng)造新的dom樹和舊的dom樹進(jìn)行diff算法對比,節(jié)省大量性能,尤其是在dom結(jié)構(gòu)復(fù)雜的時候
組件接受新的state或者props時調(diào)用.默認(rèn)情況下,該方法返回true,當(dāng)返回值為false時,則不再向下執(zhí)行其他生命周期方法.
3.componentWillUpdata(nextProps, nextState)
組件加載時不調(diào)用,只有在組件將要更新時才調(diào)用,此時可以修改state
最后一次更改props和state的機(jī)會,組件將要更新的時候觸發(fā)
重新再渲染一遍組件,更新dom樹
在最近的更改被提交到DOM元素前,render()之后,使得組件可以在更改之前獲得當(dāng)前值,此生命周期返回的任意值都會傳給componentDidUpdate()的第三個參數(shù)?!?不常用’
dom更新完成時,更新DOM節(jié)點的操作可放在這里進(jìn)行。
shouldComponentUpdate()>render()>getSnapshotBeforeUpdate()>componentDidUpdate()
static getDerivedStateFromProps()>shouldComponentUpdate()>render()>getSnapshotBeforeUpdate()>componentDidUpdate()
在組件卸載之前調(diào)用,可以在此方法中執(zhí)行任何需要清理的工作,比如定時器,事件回收,取消網(wǎng)絡(luò)請求等等,或者清理在componentDidMount()中創(chuàng)建的任何監(jiān)聽事件等
componentDidMount(){console.log('componentDidMount');// 開啟長連接// 開定時器// 調(diào)接口this.timer=setTimeout(()=>{console.log('開啟定時器');},1000);}//組件卸載階段componentWillUnmount(){this.timer&&clearTimeout(this.timer);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在渲染期間,生命周期方法或構(gòu)造函數(shù)constructor()中發(fā)生錯誤時,將會調(diào)用componentDidCatch()方法
componentDidCatch(error,info){}
1
2
3
不會處理捕獲到下面引發(fā)的錯誤
componentDidCatch()本身錯誤
服務(wù)端渲染(SSR)
事件處理,因為事件處理不發(fā)生在React渲染時,報錯不影響渲染
異步代碼
很多團(tuán)隊還沒有更新到16版本,所以16版本之前的生命周期還是需要知道的.不過16版本也是基于之前的修改的,只不過是添加了幾個鉤子函數(shù)和棄用了幾個鉤子函數(shù)
加載的時候調(diào)用一次,可以初始化state,也可以接收props
設(shè)置默認(rèn)的props,也可以用defaultProps設(shè)置組件的默認(rèn)屬性
初始化state,可以直接在constructor()中定義this.state
組件加載時只調(diào)用,以后組件更新不調(diào)用,整個生命周期只調(diào)用一次,此時可以修改state
創(chuàng)建虛擬dom,進(jìn)行diff運算,更新dom樹都在此進(jìn)行
組件渲染之后值調(diào)用一次
組件加載時不調(diào)用,組件接受新的props時調(diào)用
2.shouldComponentUpdate(nextProps,nextState)
組件接受到新的props或者state時調(diào)用,return true會更新dom,使用diff算法更新,return false阻止更新(不調(diào)用render) 性能優(yōu)化的關(guān)鍵一環(huán)
3.componentWillUpdate(nextProps,nextState)
組件加載時不調(diào)用,只有組件在更新時才調(diào)用,此時可以修改state
創(chuàng)建虛擬dom,diff運算,更新dom樹
組件更新完成后調(diào)用
在組件卸載之前調(diào)用,清理定時器,事件回收,釋放某些東西時使用
importReactfrom'react';exportdefaultclassOldLifeextendsReact.Component{constructor(props){super(props);//getDefaultProps: 接收初始props//getInitialState: 初始化state}state={}componentWillMount(){//組件掛載前觸發(fā)}render(){return(<div></div>);}componentDidMount(){//組件掛載完成后觸發(fā)}componentWillReceiveProps(nextProps){//接收到新的props時觸發(fā)}shouldComponentUpdate(nextProps,nextState){//進(jìn)行性能優(yōu)化? returntrue;}componentDidUpdate(){//組件更新后觸發(fā)}componentWillUnmount(){//卸載時觸發(fā)//this.timer&&clearTimeout(this.time}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
React16新的生命周期棄用了componentWillMount,componentWillReceiveProps,componentWillUpdate
新增了?getDerivedStateFromProps,getSnapshotBeforeUpdate來代替棄用的三個鉤子函數(shù)componentWillMount,componentWillReceiveProps,componentWillUpdate
React16并沒有刪除這三個鉤子函數(shù),但是不能和新的鉤子函getDerivedStateFromProps,getSnapshotBeforeUpdate數(shù)混用,React17將會刪除componentWillMount,componentWillReceiveProps,omponentWillUpdate
新增了對錯誤的處理?componentDidCatch
老版本生命周期圖示:
新版本生命周期圖示: