摘要:接上文,流程圖掛載是我們重點(diǎn)關(guān)注對(duì)象之一。賦值實(shí)例更新器流程圖中返回的對(duì)象,其實(shí)就是模塊。目前我們并不會(huì)使用,但是我們必須了解的是,非常非常重要,大名鼎鼎的方法就會(huì)使用到這個(gè)。這個(gè)方法是我們目前碰到的第一個(gè)生命周期事件鉤子。
接上文,
React流程圖:
https://bogdan-lyashenko.gith...
componentMount是我們重點(diǎn)關(guān)注對(duì)象之一。 這個(gè)方法最重要的部分就是ReactCompositeComponent.mountComponent.
如果你還有印象,我提到過(guò)第一個(gè)被壓入到組件樹里的組件是TopLevelWrapper(React內(nèi)部類)。在mountComponent中,我們將掛載它。
但是,這個(gè)內(nèi)部類是一個(gè)空的包裝類。對(duì)于調(diào)試來(lái)說(shuō)毫無(wú)意義,它完全不影響流程。所以,我們暫且跳過(guò)它,先對(duì)它的子組件進(jìn)行研究。
掛載一個(gè)組件樹的過(guò)程大致如下:掛載父親組件,然后掛載它的子組件,然后是子組件的子組件,以此類推。當(dāng)TopLevelWrapper掛載后,它的子組件(ReactCompositeComponent,負(fù)責(zé)管理ExampleApplication)也會(huì)進(jìn)入到相同的步驟。
我們回到ReactCompoiteComponent一探究竟。這里面有一些關(guān)鍵點(diǎn)需要注意,接下去我們會(huì)詳細(xì)的討論里面的邏輯。
賦值實(shí)例更新器流程圖中 transaction.getUpdateQueue()返回的對(duì)象updateQueue,其實(shí)就是ReactUpdateQueue模塊。那么會(huì)為什么在這里要賦值updateQueue呢?這是因?yàn)镽eactCompositeComponent(我們正在研究的類)是各個(gè)平臺(tái)都需要使用的,但是updateQueue則在不同平臺(tái)有不同實(shí)現(xiàn),所以需要我們動(dòng)態(tài)的在掛載過(guò)程中根據(jù)不同的平臺(tái)賦予不同的值。
目前我們并不會(huì)使用updateQueue,但是我們必須了解的是,updateQueue非常非常重要,大名鼎鼎的setState方法就會(huì)使用到這個(gè)updateQueue。
在這個(gè)階段,除了對(duì)updateQueue的賦值,還會(huì)有組件實(shí)例(自定義組件)被props,context,refs擴(kuò)展的過(guò)程。
看下如下代碼:
// src endererssharedstack econcilerReactCompositeComponent.js#255 // These should be set up in the constructor, but as a convenience for // simpler class abstractions, we set them up after the fact. inst.props = publicProps; inst.context = publicContext; inst.refs = emptyObject; inst.updater = updateQueue;
這個(gè)步驟之后,就可以通過(guò)類似this.props的方式來(lái)讓實(shí)例獲取props等屬性了。
創(chuàng)建ExampleApplication實(shí)例在流程圖中,通過(guò)調(diào)用_constructComponent方法和其他幾個(gè)構(gòu)造方式,一個(gè)新的ExampleApplication實(shí)例就被創(chuàng)建出來(lái)了。我們?cè)诮M件構(gòu)造函數(shù)里寫的代碼往往也是在這里被調(diào)用的。 這里,是我們自己寫的代碼第一次真正被React系統(tǒng)調(diào)用的地方。
執(zhí)行初始掛載現(xiàn)在我們開始掛載過(guò)程,第一件事就是調(diào)用componentWillMount(前提當(dāng)然是如果有組件代碼里有指定)。這個(gè)方法是我們目前碰到的第一個(gè)生命周期事件鉤子。當(dāng)然,在后面你也會(huì)看到componentDidMount方法。在這里,我們并不直接執(zhí)行它們,我們只是將它們押入到事務(wù)隊(duì)列里。它們的真正的執(zhí)行在非常后面,是在掛載操作完成之后才執(zhí)行的。你可以在componentWillMount里調(diào)用setState方法,然后state會(huì)重新計(jì)算,但是render方法并不會(huì)被調(diào)用(如果在這里調(diào)用render方法是毫無(wú)意義的,因?yàn)榻M件都沒掛載到DOM樹上呢)
官方文檔表達(dá)了類似的意思
當(dāng)掛載事件發(fā)生前,componentWillMount方法會(huì)被立刻調(diào)用。它的調(diào)用在render方法之前,因此,在這里調(diào)用setState不會(huì)觸發(fā)重新渲染(componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state in this method will not trigger a re-rendering.)
看下源碼里是怎么做的
// src endererssharedstack econcilerReactCompositeComponent.js#476 if (inst.componentWillMount) { //.. inst.componentWillMount(); // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingStateQueue` without triggering a re-render. if (this._pendingStateQueue) { inst.state = this._processPendingState(inst.props, inst.context); } }
當(dāng)state重新計(jì)算后,我們就會(huì)調(diào)用render方法了,就是我們?cè)谖覀冏远x組件里定義的render方法。React又一次使用了我們的代碼。
接下去,我們將會(huì)創(chuàng)建一個(gè)React組件實(shí)例,嗯,又創(chuàng)建一次。我們之前已經(jīng)調(diào)用過(guò)一次this._instantiateReactComponent了,為什么這里又要調(diào)用一次呢?這是因?yàn)椋耙淮蔚恼{(diào)用,是創(chuàng)建一個(gè)ExampleApplication組件對(duì)應(yīng)的ReactCompositeComponent實(shí)例,現(xiàn)在,我們則是根據(jù)我們組件的render方法中返回的元素,創(chuàng)建子組件對(duì)應(yīng)的虛擬DOM實(shí)例。在我們的列子中,render方法返回了一個(gè)div,所以,虛擬DOM創(chuàng)建一個(gè)ReactDOMComponent的實(shí)例。當(dāng)這個(gè)實(shí)例創(chuàng)建后,我們會(huì)又一次調(diào)用ReactReconciler.mountComponent方法,但這次是一個(gè)創(chuàng)建內(nèi)部實(shí)例但過(guò)程,我們傳遞的是一個(gè)ReactDOMComponent的實(shí)例。 然后,繼續(xù)調(diào)用它的mountComponent方法。。。
(未完待續(xù))
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://hztianpu.com/yun/95798.html
摘要:源碼里有個(gè)獨(dú)立的模塊管理組件的所有子元素。第一個(gè),實(shí)例化子元素使用并掛載它們。至于具體掛載流程,基于子元素類型的不同而有不同的掛載過(guò)程。掛載的過(guò)程基本完成了。 接上文, React流程圖:https://bogdan-lyashenko.gith... 創(chuàng)建初始子組件 在之前的步驟里,組件本身的構(gòu)建已經(jīng)完成,接下去,我們分析它們的子元素??偣卜譃閮刹剑簰燧d子元素(this.mountC...
摘要:當(dāng)鼠標(biāo)事件發(fā)生時(shí),組件的最外層會(huì)進(jìn)行處理,然后通過(guò)幾層包裝器的處理后,會(huì)開始進(jìn)行批量更新操作。在這之后,會(huì)將這些事件處理成常見到樣子。 接上文, React流程圖:https://bogdan-lyashenko.gith... 回到最初 在流程圖中,也許你已經(jīng)注意到,setState方法可以通過(guò)幾種方式觸發(fā),更準(zhǔn)確的說(shuō),可以分為是否由外部引起的(也就是是否由用戶觸發(fā))。讓我們看下如下...
摘要:技術(shù)上來(lái)說(shuō),當(dāng)方法被調(diào)用后或者發(fā)生改變后,方法都會(huì)被調(diào)用。下一步,會(huì)設(shè)置為。之后,檢測(cè)當(dāng)前更新是否由更新引起的。這是因?yàn)?,使用是?dǎo)致組件持久化更新,而會(huì)被方法的返回值重新賦值。 接上文, React流程圖:https://bogdan-lyashenko.gith... 更新組件 關(guān)于組件的更新,我們先看下代碼里的注釋: 對(duì)于已掛載組件的更新過(guò)程,React會(huì)首先調(diào)用component...
摘要:接上文,流程圖我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下方法,這個(gè)也是的重要組成部分。這個(gè)問題,我們會(huì)在下一篇文章中進(jìn)行解答。。。 接上文, React流程圖:https://bogdan-lyashenko.gith... this.setState 我們已經(jīng)知道掛載的工作流程,現(xiàn)在我們換個(gè)方向研究下--setState方法,這個(gè)也是React的重要組成部分。 首先,為什么我...
摘要:接著,將返回的元素和之前的進(jìn)行比較的,以驗(yàn)證是否真的需要更新。我們看下代碼,代碼比較簡(jiǎn)單好,對(duì)應(yīng)于我們的這個(gè)列子,我們對(duì)于方法的更改并不會(huì)對(duì)方法造成影響。所以我們進(jìn)入下一步,也就是對(duì)于節(jié)點(diǎn)的更新。 接上文, React流程圖:https://bogdan-lyashenko.gith... 如果組件真的需要更新 在組件剛開始更新過(guò)程時(shí),如果有定義componentWillUpdate方...
摘要:接上文,流程圖子組件掛載我們繼續(xù)探究方法。對(duì)于我們的實(shí)例代碼而言,就是標(biāo)簽,所以沒有額外的處理過(guò)程。屬性驗(yàn)證緊接著的被調(diào)用的驗(yàn)證方法用于確保被正確設(shè)置,否則,會(huì)拋出異常。 接上文, React流程圖:https://bogdan-lyashenko.gith... 子組件掛載 我們繼續(xù)探究mount方法。 如果渲染的標(biāo)簽里有復(fù)雜的html標(biāo)簽,如video,form,textarea等...
閱讀 1298·2019-08-30 12:44
閱讀 791·2019-08-29 13:03
閱讀 2723·2019-08-28 18:15
閱讀 2556·2019-08-26 10:41
閱讀 3261·2019-08-26 10:28
閱讀 3164·2019-08-23 16:54
閱讀 2140·2019-08-23 15:16
閱讀 967·2019-08-23 14:55