摘要:組件生命周期嚴(yán)格定義了組件的生命周期,生命周期可能會(huì)經(jīng)歷如下三個(gè)過(guò)程裝載過(guò)程也就是把組件第一次在樹(shù)上渲染的過(guò)程更新過(guò)程當(dāng)組件被從新渲染的過(guò)程卸載過(guò)程組件從樹(shù)中刪除的過(guò)程。三種不同的過(guò)程,庫(kù)會(huì)調(diào)用組件的一些成員函數(shù),即生命周期函數(shù)。
3. 組件生命周期
React嚴(yán)格定義了組件的生命周期,生命周期可能會(huì)經(jīng)歷如下三個(gè)過(guò)程:
裝載過(guò)程(Mount):也就是把組件第一次在DOM樹(shù)上渲染的過(guò)程;
更新過(guò)程(Updata):當(dāng)組件被從新渲染的過(guò)程;
卸載過(guò)程(Unmount):組件從DOM樹(shù)中刪除的過(guò)程。
三種不同的過(guò)程,React庫(kù)會(huì)調(diào)用組件的一些成員函數(shù),即生命周期函數(shù)。
3.1、裝載過(guò)程
當(dāng)組件第一次被渲染時(shí),依次調(diào)用的函數(shù):
static propTypes(createClass創(chuàng)建的話:propTypes)
static defaultProps(createClass創(chuàng)建的話:getDefaultProps(){})
constructor(初始化state;createClass創(chuàng)建的話:getInitalState)
componentWillMount
render
componentDidMount
constructor
ES6中每個(gè)類(lèi)的構(gòu)造函數(shù),要?jiǎng)?chuàng)建一個(gè)組件類(lèi)的實(shí)例,便會(huì)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)
注意:并不是每個(gè)組件都需要定義自己的構(gòu)造函數(shù),無(wú)狀態(tài)的React組件往往就不需要定義構(gòu)造
函數(shù);一個(gè)React組件需要構(gòu)造函數(shù)目的:
初始化state,因?yàn)榻M件的生命周期中任何函數(shù)都可能要訪問(wèn)state,那么整個(gè)周期中第一個(gè)被調(diào)用的構(gòu)造函數(shù)便是初始化state最理想的地方;
綁定成員函數(shù)的this環(huán)境:
? - 因?yàn)樵贓S6語(yǔ)法下,類(lèi)的每個(gè)成員函數(shù)在執(zhí)行時(shí)的this并不是和類(lèi)實(shí)例自動(dòng)綁定的;
? - 而在構(gòu)造函數(shù)中this就是當(dāng)前組件實(shí)例,所以,為了方便將來(lái)調(diào)用,往往在構(gòu)造函數(shù)中將這個(gè)實(shí)例的特定函數(shù)綁定this為當(dāng)前類(lèi)實(shí)例:
... constructor(props){ super(props); this.onClickFunc = this.onClickFunc.bind(this); }
getInitialState和getDefaultProps
? 1. getInitialState函數(shù)的返回值用來(lái)初始化組件的this.state;
? 2. getInitialState只出現(xiàn)在裝載過(guò)程,也就是說(shuō)一個(gè)組件的整個(gè)生命周期過(guò)程中,這個(gè)函數(shù)只被調(diào)用一次;
? 3. getDefaultProps函數(shù)的返回值可以作為props的初始值;
? 4. 兩個(gè)函數(shù)都只有在使用React.createClass方法創(chuàng)建組件類(lèi)時(shí)才會(huì)用到:
const Sample = React.createClass({ getInitialState: function() { ? ? ? ?return {foo: "返回值將作為this.state的初始值"}; }, getDefaultProps: function() { ? ? ? ?return {sampleProp: "作為props的初始值"} } })
?5. React.createClass創(chuàng)建方法已經(jīng)逐漸被Facebook官方廢棄
? 6. 使用ES6時(shí),在構(gòu)造函數(shù)中通過(guò)this.state賦值完成狀態(tài)初始化;通過(guò)給類(lèi)屬性(注意是類(lèi)屬性,而不是類(lèi)的實(shí)例對(duì)象的屬性)defaultProps賦值指定的props初始值:
class Sample extends React.Component{ constructor (props){ super(props); ? ? ? ?this.state = {foo: "初始值"} } } ? ?Sample.defaultProps = { sampleProps: 0 }
render
render函數(shù)是React組件中最重要的函數(shù),一個(gè)React組件可以忽略其他所有函數(shù)都不實(shí)現(xiàn),但一定要實(shí)現(xiàn)render函數(shù),因?yàn)樗蠷eact組件的父類(lèi)React.Component類(lèi)對(duì)除了render之外的生命周期函數(shù)都有默認(rèn)實(shí)現(xiàn)。
通常一個(gè)組件要發(fā)揮作用,總是要渲染一些東西,render函數(shù)并不做實(shí)際的渲染動(dòng)作,它只是返回一個(gè)JSX描述結(jié)構(gòu),最終由React來(lái)操作渲染過(guò)程;
當(dāng)某個(gè)特殊的組件作用不是渲染界面,或者沒(méi)有東西可畫(huà)時(shí),可讓render函數(shù)返回null或者false,即告訴React此組件不渲染任何DOM元素;
注意:render函數(shù)應(yīng)該是一個(gè)純函數(shù),完全根據(jù)this.state和this.props來(lái)決定返回的結(jié)果,而且不要產(chǎn)生任何副作用,不要在render函數(shù)中調(diào)用this.setState去改變狀態(tài),因?yàn)橐粋€(gè)純函數(shù)不應(yīng)該引起狀態(tài)的改變。
componentWillMount和componentDidMount
在裝載過(guò)程中,componentWillMount會(huì)在render函數(shù)之前調(diào)用,此時(shí)還沒(méi)有任何東西渲染出來(lái),即使調(diào)用this.setState修改狀態(tài)也不會(huì)發(fā)生重新繪制;
componentDidMount在render函數(shù)之后調(diào)用,但render調(diào)用之后并不會(huì)立即調(diào)用,而是在render函數(shù)返回的東西已經(jīng)引發(fā)了渲染,組件已經(jīng)被‘裝載’到了DOM樹(shù)上后,componentDidMount才被調(diào)用,此時(shí)已繪制出真實(shí)的DOM樹(shù);
注意:
3.2、更新過(guò)程render函數(shù)本身并不往DOM樹(shù)上渲染或者裝載內(nèi)容,它只是返回一個(gè)表示JSX表示的對(duì)象(及組件實(shí)例),然后由React庫(kù)根據(jù)返回的對(duì)象決定如何渲染;
而React庫(kù)肯定是要把所有組件返回的結(jié)果綜合起來(lái),才能知道如何產(chǎn)生對(duì)應(yīng)的DOM修改;
所以只有React庫(kù)調(diào)用所有組件的render函數(shù)之后,才有可能完成DOM裝載,這時(shí)候才會(huì)依調(diào)用componentDidMount函數(shù)作為裝載的收尾。
componentWillMount可以在服務(wù)器和瀏覽器端被調(diào)用,而componentDidMount只能在瀏覽器端被調(diào)用(因?yàn)閏omponentDidMount是在‘裝載’完成之后被調(diào)用,且‘裝載’是一個(gè)創(chuàng)建組件并放到DOM樹(shù)上的過(guò)程,而服務(wù)器端渲染通過(guò)React組件產(chǎn)生的只是一個(gè)純粹的字符串,并不會(huì)產(chǎn)生DOM樹(shù),即在服務(wù)器端不可能完成‘裝載過(guò)程’所以無(wú)法調(diào)用componentDidMount)
隨著用戶(hù)的操作改變展示的內(nèi)容,當(dāng)props或者state被修改時(shí),就會(huì)引發(fā)組件的更新過(guò)程;
更新過(guò)程會(huì)依次調(diào)用以下生命周期函數(shù),其中render函數(shù)和“裝載”過(guò)程一樣:
?- componentWillReceiveProps
?- shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
并不是所有的更新過(guò)程都會(huì)執(zhí)行全部函數(shù)。
componentWillReceiveProps(nextProps)
并不是只有在組件的props發(fā)生改變的時(shí)候才會(huì)調(diào)用此函數(shù);
在更新過(guò)程,只要是父組件的render函數(shù)被調(diào)用,在render函數(shù)里被渲染的子組件就會(huì)經(jīng)歷更新過(guò)程,不管父組件傳給子組件的props有沒(méi)有改變,都會(huì)觸發(fā)子組件的componentWillReceiveProps函數(shù);
注意:通過(guò)this.setState方法觸發(fā)的更新過(guò)程不會(huì)調(diào)用這個(gè)函數(shù);
因?yàn)椋@個(gè)函數(shù)適合根據(jù)新的props值(也就是參數(shù)nextProps)來(lái)計(jì)算是不是要更新內(nèi)部狀態(tài)state;而更新內(nèi)部狀態(tài)的方法是this.setState,如果this.setState的調(diào)用導(dǎo)致componentWillReceiveProps再調(diào)用,那將是一個(gè)死循環(huán)。
shouldComponentUpdate(nextProps,nextState)
除了render函數(shù),shouleComponentUpdate可能是生命周期函數(shù)中最重要的一個(gè)函數(shù);
因?yàn)閞ender函數(shù)決定了該渲染什么,shouldComponentUpdate決定了一個(gè)組件什么時(shí)候不需要渲染;
render和shouldComponentUpdate也是React生命周期函數(shù)中唯二兩個(gè)要求有返回結(jié)果的函數(shù);
render函數(shù)的返回結(jié)果用于構(gòu)建DOM對(duì)象,shouldComponentUpdate函數(shù)返回一個(gè)布爾值,告訴React庫(kù)這個(gè)組件這次更新過(guò)程是否繼續(xù);
在更新過(guò)程中,React庫(kù)首先調(diào)用shouldComponentUpdate函數(shù),如果這個(gè)函數(shù)返回true,那就繼續(xù)更新過(guò)程,接下來(lái)調(diào)用render,反之則終止此次更新過(guò)程;
shouldComponentUpdate的參數(shù)就是接下來(lái)的props和state值;我們可以根據(jù)這兩個(gè)參數(shù),外加this.props和this.state來(lái)判斷返回true或false,從而避免不必要的更新。
componentWillUpdate和componentDidUpdate
如果組件的shouldComponentUpdate返回true,React接下來(lái)調(diào)用componentWillUpdate、render和componentDidUpdate;
和“裝載”過(guò)程不同,這對(duì)函數(shù)都可以在服務(wù)器和瀏覽器更新階段調(diào)用
不過(guò),通常在使用React做服務(wù)端渲染時(shí),基本不會(huì)經(jīng)歷更新過(guò)程,因?yàn)榉?wù)器端只需要產(chǎn)出HTML字符串,而一個(gè)裝載過(guò)程就足夠產(chǎn)出HTML字符串了,所以正常情況下,服務(wù)器端不會(huì)調(diào)用componentDidUpdate函數(shù),如果調(diào)用了,說(shuō)明程序有錯(cuò),需要改進(jìn)。
3.2、卸載過(guò)程React組件的卸載過(guò)程只涉及一個(gè)函數(shù)componentWillUnmount,
當(dāng)React組件要從DOM樹(shù)上刪除之前,對(duì)應(yīng)的componentWillUnmount函數(shù)會(huì)被調(diào)用,所以這個(gè)函數(shù)適合做一些清理性的工作。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93116.html
摘要:卸載階段組件卸載和銷(xiāo)毀老版生命周期之前的生命周期初始化階段涉及個(gè)鉤子函數(shù)這些方法會(huì)在組件初始化的時(shí)候被調(diào)用,只跟實(shí)例的創(chuàng)建有關(guān)。 前言:React 的版本從 v15 到 v16.3 ,再到v16.4,現(xiàn)在最新的版本是 v16.8了。其中最大的變化可能是React Hooks的加入,而最令人困惑的卻是它的生命周期,新舊生命周期函數(shù)混雜在一起,難免會(huì)讓許多新來(lái)者有很多困惑。所以這一篇我們來(lái)...
摘要:組件裝載過(guò)程裝載過(guò)程依次調(diào)用的生命周期函數(shù)中每個(gè)類(lèi)的構(gòu)造函數(shù),創(chuàng)造一個(gè)組件實(shí)例,當(dāng)然會(huì)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)。組件需要構(gòu)造函數(shù),是為了以下目的初始化,因?yàn)樯芷谥腥魏魏瘮?shù)都有可能訪問(wèn),構(gòu)造函數(shù)是初始化的理想場(chǎng)所綁定成員函數(shù)的環(huán)境。 React系列---React(一)初識(shí)ReactReact系列---React(二)組件的prop和stateReact系列---之React(三)組件的生...
摘要:更新階段卸載階段兄弟節(jié)點(diǎn)之間的通信主要是經(jīng)過(guò)父組件和也是通過(guò)改變父組件傳遞下來(lái)的實(shí)現(xiàn)的,滿足的設(shè)計(jì)遵循單向數(shù)據(jù)流模型,因此任何兩個(gè)組件之間的通信,本質(zhì)上都可以歸結(jié)為父子組件更新的情況。 你真的了解 React 生命周期嗎? React 生命周期很多人都了解,但通常我們所了解的都是 單個(gè)組件 的生命周期,但針對(duì) Hooks 組件、多個(gè)關(guān)聯(lián)組件(父子組件和兄弟組件) 的生命周期又是怎么樣的...
摘要:本文主要介紹之后的生命周期。該方法有兩個(gè)參數(shù)和返回值為對(duì)象不需要返回整體,把需要改變的返回即可。必須有一個(gè)返回值,返回的數(shù)據(jù)類(lèi)型可以有。此生命周期主要用于優(yōu)化性能。最后,說(shuō)明一點(diǎn)這三個(gè)生命周期在未來(lái)版本中會(huì)被廢棄。 React16.3.0開(kāi)始,生命周期進(jìn)行了一些變化。本文主要介紹React16.3.0之后的生命周期。 React16.3.0之前生命周期: 16版本之前的react組件的...
摘要:所以對(duì)于組件更新階段的組件生命周期,我們簡(jiǎn)單提及并且提供一些資料給大家。這里為了知識(shí)的完整,補(bǔ)充關(guān)于更新階段的組件生命周期你可以通過(guò)這個(gè)方法控制組件是否重新渲染。大家對(duì)這更新階段的生命周期比較感興趣的話可以查看官網(wǎng)文檔。 React.js 小書(shū) Lesson20 - 更新階段的組件生命周期 本文作者:胡子大哈本文原文:http://huziketang.com/books/react...
閱讀 2415·2021-09-08 09:45
閱讀 3363·2021-09-08 09:45
閱讀 3106·2019-08-30 15:54
閱讀 3361·2019-08-26 13:54
閱讀 1417·2019-08-26 13:26
閱讀 1394·2019-08-26 13:23
閱讀 917·2019-08-23 17:57
閱讀 2187·2019-08-23 17:14