摘要:組件裝載過程裝載過程依次調(diào)用的生命周期函數(shù)中每個(gè)類的構(gòu)造函數(shù),創(chuàng)造一個(gè)組件實(shí)例,當(dāng)然會(huì)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)。組件需要構(gòu)造函數(shù),是為了以下目的初始化,因?yàn)樯芷谥腥魏魏瘮?shù)都有可能訪問,構(gòu)造函數(shù)是初始化的理想場(chǎng)所綁定成員函數(shù)的環(huán)境。
React系列---React(一)初識(shí)React
React系列---React(二)組件的prop和state
React系列---之React(三)組件的生命周期
React嚴(yán)格定義了組件的生命周期,共3個(gè)過程:
1) 裝載過程(Mount):組件第一次在DOM樹中渲染的過程;
2) 更新過程(Update):組件被重新渲染的過程;
3) 卸載過程(Unmount):組件從DOM樹中刪除的過程。
三種不同的過程,React庫會(huì)依次調(diào)用組件的一些生命周期函數(shù)。所以,定義一個(gè)React組件,實(shí)際上就是定制這些生命周期函數(shù)。
組件裝載過程裝載過程依次調(diào)用的生命周期函數(shù):
constructor getInitialState getDefaultProps
componentWillMount
render
componentDidMount
ES6中每個(gè)類的構(gòu)造函數(shù),創(chuàng)造一個(gè)組件實(shí)例,當(dāng)然會(huì)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)。
并不是每個(gè)組件都需要定義構(gòu)造函數(shù)。后面會(huì)看到無狀態(tài)React組件是不需要定義構(gòu)造函數(shù)的。
React組件需要構(gòu)造函數(shù),是為了以下目的:
1) 初始化state,因?yàn)樯芷谥腥魏魏瘮?shù)都有可能訪問state,構(gòu)造函數(shù)是初始化state的理想場(chǎng)所;
2) 綁定成員函數(shù)的this環(huán)境。
這2個(gè)函數(shù),只有在通過React.createClass方法創(chuàng)造的組件類才會(huì)發(fā)生作用。這是過時(shí)的方法,ES6創(chuàng)造的組件中用不到。
假如用React.createClass定義組件Sample,設(shè)定內(nèi)部狀態(tài)foo初始值為bar,同時(shí)設(shè)定sampleProp的prop初始值為0,代碼如下:
const Sample = React.createClass({ getInitialState: function(){ return {foo: "bar"}; }, getDefaultProps: function() { return {sampleProp: 0} } });
用ES6的話,在構(gòu)造函數(shù)中給this.state賦值完成狀態(tài)初始化,給類的屬性defaultProps賦值指定props初始值:
class Sample extends React.Component { constructor(props) { super(props); this.state = {foo: "bar"}; } } Sample.defaultProps = { return {sampleProp: 0}; };render
React組件可以忽略其他所有函數(shù)都不實(shí)現(xiàn),但是一定要實(shí)現(xiàn)render函數(shù),因?yàn)樗蠷eact組件的父類React.Component類對(duì)除render之外的生命周期函數(shù)都有默認(rèn)實(shí)現(xiàn)。render函數(shù)并不做實(shí)際的渲染動(dòng)作,它只負(fù)責(zé)返回一個(gè)JSX描述的結(jié)構(gòu),最終由React來操作渲染過程。
render函數(shù)應(yīng)該是一個(gè)純函數(shù),完全根據(jù)this.state和this.props來決定返回的結(jié)果,而且不要產(chǎn)生任何副作用。在render函數(shù)中去調(diào)用this.setState是錯(cuò)誤的,因?yàn)橐粋€(gè)純函數(shù)不應(yīng)該引起狀態(tài)的變化。
componentWillMount和componentDidMount裝載過程中,componentWillMount和componentDidMount分別在render之前和之后調(diào)用。
不過,通常不定義componentWillMount函數(shù),因?yàn)轭櫭剂x,它發(fā)生在將要裝載的時(shí)候,這個(gè)時(shí)候一切都遲了,即使再調(diào)用this.setState()修改狀態(tài)也不會(huì)引發(fā)重新繪制了。換句話說,所有可以在componentWillMount中做的事情,都可以提前到constructor中去做??梢哉J(rèn)為這個(gè)函數(shù)存在的目的就是為了和componentDidMount對(duì)稱。
而componentDidMount作用就大了。不過要注意的是,componentDidMount被調(diào)用時(shí),前置render函數(shù)返回的東西必定已經(jīng)完成了渲染,組件已經(jīng)被“裝載”到DOM樹上了。
還是以ControlPanel為例,在ControlPanel中有三個(gè)Counter組件,我們修改Counter代碼,讓裝載過程的所有生命周期函數(shù)都用console.log輸出函數(shù)名和caption值,比如,componentWillMount函數(shù)如下:
componentWillMount() { console.log("enter componentWillMount " + this.props.caption); }
在瀏覽器的console里我們能看到:
enter constructor: First enter componentWillMount First enter render First enter constructor: Second enter compomentWillMount: Second enter render Second enter constructor: Third enter componentWillMount Third enter render Third enter componentDidMount First enter componentDidMount Second enter componentDidMount Third
可以清楚的看到,由于渲染需要一定的時(shí)間,所以三個(gè)組件的componentDidMount是在最后才連在一起被調(diào)用的。
componentWillMount和componentDidMount還有一個(gè)區(qū)別,就是componentWillMount可以在服務(wù)端被調(diào)用,也可以在瀏覽器端被調(diào)用;而componentDidMount只能在瀏覽器端被調(diào)用。
componentDidMount中,可通過AJAX獲取數(shù)據(jù)來填充組件內(nèi)容。在componentDidMount被調(diào)用時(shí),組件已經(jīng)被裝載到DOM樹了,也可以放心的讓React和其他操縱DOM的庫(如jQuery)配合工作了。
組件更新過程當(dāng)組件被裝載到DOM樹上之后,用戶在網(wǎng)頁上看到了第一印象,但是要提供更好的交互體驗(yàn),就要讓組件可以隨著用戶操作改變展現(xiàn)的內(nèi)容,當(dāng)props或state被修改時(shí),就會(huì)引發(fā)組件的更新過程。
更新過程依次調(diào)用以下生命周期函數(shù):
1) componentWillReceiveProps
2) shouldComponentUpdate
3) componentWillUpdate
4) render
5) componentDidUpdate
當(dāng)組件的props發(fā)生改變時(shí)會(huì)被調(diào)用。父組件的render被調(diào)用時(shí),被渲染的子組件也會(huì)經(jīng)歷更新過程,不管父組件傳給子組件的props有沒有改變,都會(huì)觸發(fā)子組件的componentWillReceiveProps。
我們?cè)贑ounter組件類里增加這個(gè)函數(shù)定義,并在console輸出一些文字:
componentWillReceiveProps(nextProps) { console.log("enter componentWillReceiveProps " + this.props.caption) }
在ControlPanel組件的render函數(shù)中,也做如下修改:
render() { console.log("enter ControlPanel render"); return (...); }
除了在ControlPanel的render函數(shù)入口增加console輸出,還增加了一個(gè)按鈕,當(dāng)這個(gè)按鈕被點(diǎn)擊時(shí),調(diào)用this.forceUpdate(),每個(gè)React組件都可以通過forceUpdate()強(qiáng)行引發(fā)一次組件重繪。
在網(wǎng)頁上點(diǎn)擊父組件新增的重繪按鈕,看到瀏覽器console輸出:
enter ControlPanel render enter componentWillReceiveProps First enter render First enter componentWillReceiveProps Second enter render Second enter componentWillReceiveProps Third enter render Third
可以看到,父組件引發(fā)重繪后,首先是父組件ControllPanel的render被調(diào)用,隨后依次3個(gè)Counter子組件的componentWillReceiveProps和render函數(shù)被調(diào)用。
然而,父組件傳給三個(gè)子組件的props值一直沒有變化,這就驗(yàn)證了componentWillReceiveProps并不只是當(dāng)props值變化時(shí)才被調(diào)用,父組件render時(shí),子組件的componentWillReceiveProps也會(huì)被調(diào)用。
在網(wǎng)頁中,我們?cè)賴L試點(diǎn)擊第一個(gè)Counter子組件的“+”按鈕,可以看到瀏覽器console輸出:
enter render First
明顯,只有第一個(gè)子組件Counter的render函數(shù)被調(diào)用,因?yàn)榻M件的this.setState()函數(shù)不會(huì)引發(fā)componentWillReceiveProps調(diào)用。
shouldComponentUpdate(nextProps, nextState)shouldComponentUpdate函數(shù)返回一個(gè)布爾值,告訴React庫這個(gè)組件在這次更新過程中是否要繼續(xù)。返回false會(huì)停止更新過程,就此結(jié)束,也不會(huì)引發(fā)后續(xù)的渲染了。
這個(gè)函數(shù)能夠大大提升React組件的性能,不管React的組件渲染有多快,如果發(fā)現(xiàn)沒有必要重新渲染,就干脆不要渲染。
修改Counter組件類增加shouldComponentUpdate函數(shù)的定義:
shouldComponentUpdate(nextProps, nextState) { return (nextProps.caption !== this.props.caption) || (nextState.count !== this.state.count); }componentWillUpdate和componentDidUpdate
如果組件的shouldComponentUpdate返回true,接下來會(huì)依次調(diào)用componentWillUpdate、render和componentDidUpdate函數(shù)。
在介紹componentDidMount函數(shù)時(shí),說到可以利用componentDidMount函數(shù)執(zhí)行其他UI代碼庫,比如jQuery代碼。那么現(xiàn)在,組件被更新時(shí),也需要在componentDidUpdate函數(shù)再次調(diào)用jQuery代碼。
組件卸載過程React組件的卸載過程只涉及一個(gè)函數(shù)componentWillUnmount,這個(gè)函數(shù)適合做一些清理工作。這些清理工作往往和componentDidMount有關(guān),比如你在componentDidMount中用非React的方法創(chuàng)造了一些DOM元素,如果撒手不管會(huì)造成內(nèi)存泄漏,那就需要在componentWillUnmount中把這些DOM元素清理掉。
代碼:https://github.com/zhutx/reac...
React系列---React(一)初識(shí)React
React系列---React(二)組件的prop和state
React系列---之React(三)組件的生命周期
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83673.html
摘要:用于規(guī)范的類型與必需的狀態(tài)。表示由組件更改的數(shù)據(jù),通常是通過與用戶的交互來更改的。為了實(shí)現(xiàn)的修改,需要注冊(cè)事件處理程序到相應(yīng)的元素上。當(dāng)事件發(fā)生時(shí),將更新后的值是從中檢索,并通知組件。通常情況下,該函數(shù)初始化狀態(tài)使用,,或其他數(shù)據(jù)存儲(chǔ)。 前言 上一篇文章中,我們講到了JSX的一些用法和注意事項(xiàng),這次我們來講react中最基礎(chǔ)也是特別重要的內(nèi)容:組件。這篇文章包含組件的以下內(nèi)容:狀態(tài)、屬...
摘要:系列一初識(shí)系列二組件的和系列三組件的生命周期是推出的一個(gè)庫,它的口號(hào)就是用來創(chuàng)建用戶界面的庫,所以它只是和用戶界面打交道,可以把它看成中的視圖層。系列一初識(shí)系列二組件的和系列三組件的生命周期 React系列---React(一)初識(shí)ReactReact系列---React(二)組件的prop和stateReact系列---React(三)組件的生命周期 showImg(https://...
摘要:因?yàn)槭巧钊胂盗形恼?,本文不?huì)仔細(xì)介紹每個(gè)生命周期方法的使用,而是會(huì)重點(diǎn)講解在使用組件生命周期時(shí),經(jīng)常遇到的疑問和錯(cuò)誤使用方式。父組件發(fā)生更新導(dǎo)致的組件更新,生命周期方法的調(diào)用情況同上所述。 文:徐超,《React進(jìn)階之路》作者授權(quán)發(fā)布,轉(zhuǎn)載請(qǐng)注明作者及出處 React 深入系列4:組件的生命周期 React 深入系列,深入講解了React中的重點(diǎn)概念、特性和模式等,旨在幫助大家加深...
摘要:因?yàn)槭巧钊胂盗形恼?,本文不?huì)仔細(xì)介紹每個(gè)生命周期方法的使用,而是會(huì)重點(diǎn)講解在使用組件生命周期時(shí),經(jīng)常遇到的疑問和錯(cuò)誤使用方式。父組件發(fā)生更新導(dǎo)致的組件更新,生命周期方法的調(diào)用情況同上所述。 React 深入系列,深入講解了React中的重點(diǎn)概念、特性和模式等,旨在幫助大家加深對(duì)React的理解,以及在項(xiàng)目中更加靈活地使用React。 組件是構(gòu)建React應(yīng)用的基本單位,組件需要具備數(shù)據(jù)...
摘要:給賦值也是構(gòu)造函數(shù)的工作之一。在的構(gòu)造函數(shù)中,還給兩個(gè)成員函數(shù)綁定了當(dāng)前的執(zhí)行環(huán)境,因?yàn)榉绞絼?chuàng)建的組件并不自動(dòng)給我們綁定到當(dāng)前實(shí)例對(duì)象。我們可以利用的功能,避免判斷邏輯這種充斥在構(gòu)造函數(shù)之中,讓代碼更優(yōu)。 React系列---React(一)初識(shí)ReactReact系列---React(二)組件的prop和stateReact系列---React(三)組件的生命周期 組件是React...
閱讀 1142·2021-09-22 15:32
閱讀 1737·2019-08-30 15:53
閱讀 3270·2019-08-30 15:53
閱讀 1423·2019-08-30 15:43
閱讀 467·2019-08-28 18:28
閱讀 2585·2019-08-26 18:18
閱讀 679·2019-08-26 13:58
閱讀 2543·2019-08-26 12:10