摘要:模型模型負(fù)責(zé)底層框架的構(gòu)建工作它擁有一整套的標(biāo)簽并負(fù)責(zé)虛擬節(jié)點(diǎn)及其屬性的構(gòu)建更新刪除等工作其實(shí)構(gòu)建一套簡(jiǎn)易模型并不復(fù)雜它只需要具備一個(gè)標(biāo)簽所需的基本元素即可標(biāo)簽名屬性樣式子節(jié)點(diǎn)唯一標(biāo)識(shí)中的節(jié)點(diǎn)稱為它分為種類型其中又分為和創(chuàng)建元素輸入輸出通過(guò)
Virtual DOM模型
1.Virtual DOM模型負(fù)責(zé)Virtual DOM底層框架的構(gòu)建工作,它擁有一整套的Virtual DOM標(biāo)簽,
并負(fù)責(zé)虛擬節(jié)點(diǎn)及其屬性的構(gòu)建,更新,刪除等工作.
2.其實(shí),構(gòu)建一套簡(jiǎn)易Virtual DOM模型并不復(fù)雜,它只需要具備一個(gè)DOM標(biāo)簽所需的基本元素即可.
{ // 標(biāo)簽名 tagName: "div", // 屬性 properties: { // 樣式 style: {} }, // 子節(jié)點(diǎn) children: [], // 唯一標(biāo)識(shí) key: 1 }
3.Virtual DOM中的節(jié)點(diǎn)稱為ReactNode,它分為3種類型:ReactElement,ReactFragment,ReactText.
其中,ReactElement又分為ReactComponentElement和ReactDOMElement.
// 輸入jsx const app = ; // 輸出js const app = React.createElement( Nav, {color: "blue"}, React.createElement(Profile, null, "click") );
通過(guò)jsx創(chuàng)建的虛擬元素最終會(huì)被編譯成調(diào)用React的createElement方法
// createElement只是做了簡(jiǎn)單修正,返回一個(gè)ReactElement實(shí)例對(duì)象 // 也就是虛擬元素的實(shí)例 ReactElement.createElement = function(type, config, children) { // 初始化參數(shù) var propName; var props = {}; var key = null; var ref = null; var self = null; var source = null; // 如果存在config,則提取里面的內(nèi)容 if (config != null) { ref = config.ref === undefined ? null : config.ref; key = config.key === undefined ? null : "" + config.key; self = config._self === undefined ? null : config._self; source = config._source === undefined ? null : config._source; // 復(fù)制config里的內(nèi)容到props(id和className等) for (propName in config) { if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } } // 處理children,全部掛載到props的children屬性上,如果只有一個(gè)參數(shù),直接賦值給children // 否則做合并處理 var childrenLength = arguments.length - 2; if (childrenLength === 1) { props.children = children; } else if (childrenLength > 1) { var childArray = Array(childrenLength); for (var i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 2]; } props.children = childArray; } // 如果某個(gè)prop為空且存在默認(rèn)的prop,則將默認(rèn)prop賦給當(dāng)前的prop if (type && type.defaultProps) { var defaultProps = type.defaultProps; for (propName in defaultProps) { if (typeof props[propName] === "undefined") { props[propName] = defaultProps[propName] } } } // 返回一個(gè)ReactElement實(shí)例對(duì)象 return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); }初始化組件入口
1.當(dāng)使用React創(chuàng)建組件時(shí),首先會(huì)調(diào)用instantiateReactComponent,這就是初始化組件的入口函數(shù),
它通過(guò)判斷node類型來(lái)區(qū)分不同組件的入口.
// 初始化組件入口 function instantiateReactComponent(node, parentCompositeType) { var instance; // 空組件 (ReactEmptyComponent) if (node === null || node === false) { instance = ReactEmptyComponent.create(instantiateReactComponent); } if (typeof node === "object") { var element = node; if (typeof element.type === "string") { // DOM標(biāo)簽 (ReactDOMComponent) instance = ReactNativeComponent.createInternalComponent(element); } else if (isInternalComponentType(element.type)) { // 不是字符串表示的自定義組件暫無(wú)法使用,此處將不做組件初始化操作 instance = new element.type(element); } else { // 自定義組件 instance = new ReactCompositeComponentWrapper(); } } else if (typeof node === "string" || typeof node === "number") { // 字符串或數(shù)字 instance = ReactNativeComponent.createInstanceForText(node); } else { // 不做處理 } // 設(shè)置實(shí)例 instance.construct(node); // 初始化參數(shù) instance._mountIndex = 0; instance._mountImage = null; return instance; }文本組件
1.當(dāng)node類型為文本節(jié)點(diǎn)時(shí)是不算Virtual DOM元素的,但React為了保持渲染的一致性,
將其封裝為文本組件ReactDOMTextComponent.
1.Virtual DOM模型涵蓋了幾乎所有的原生DOM標(biāo)簽,如
,等. 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。 轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84660.html 摘要:前言的基本概念組件的構(gòu)建方法以及高級(jí)用法這背后的一切如何運(yùn)轉(zhuǎn)深入內(nèi)部的實(shí)現(xiàn)機(jī)制和原理初探源碼代碼組織結(jié)構(gòu)包含一系列的工具方法插件包含一系列同構(gòu)方法包含一些公用或常用方法如等包含一些測(cè)試方法等包含一些邊界錯(cuò)誤的測(cè)試用例是代碼的核心部分它包含了
前言
React的基本概念,API,組件的構(gòu)建方法以及高級(jí)用法,這背后的一切如何運(yùn)轉(zhuǎn),深入Virtual DOM內(nèi)部的實(shí)現(xiàn)機(jī)制和原理.
初探Rea... 摘要:調(diào)用棧是這樣的這里生成的我們將其命名為,它將作為參數(shù)傳入到。整個(gè)的調(diào)用棧是這樣的組件間的層級(jí)結(jié)構(gòu)是這樣的到此為止,頂層對(duì)象已經(jīng)構(gòu)造完畢,下一步就是調(diào)用來(lái)自的方法,進(jìn)行頁(yè)面的渲染了。通過(guò)表達(dá)的結(jié)構(gòu)最終會(huì)轉(zhuǎn)化為一個(gè)純對(duì)象,用于下一步的渲染。
歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo);
一、前言... 摘要:本文將要講解的調(diào)用棧是下面這個(gè)樣子的平臺(tái)無(wú)關(guān)相關(guān)如果看源碼,我們會(huì)留意到很多相關(guān)的代碼,我們暫時(shí)先將其忽略,會(huì)在后續(xù)的文章中進(jìn)行講解。現(xiàn)在我們來(lái)看一下各實(shí)例間的關(guān)系目前為止的調(diào)用棧平臺(tái)無(wú)關(guān)相關(guān)下一篇講解三總結(jié)本文講解了轉(zhuǎn)化為的過(guò)程。
歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo);
一、前言
R... 摘要:作為聲明式的框架,接管了所有頁(yè)面更新相關(guān)的操作。是用于內(nèi)部操作的實(shí)例,這里將它的初始化為空數(shù)組并插入一個(gè)新的。連續(xù)次后,期望的結(jié)果應(yīng)該是。原因很簡(jiǎn)單,因?yàn)榇蔚臅r(shí)候,取到的都是在完后不會(huì)同步更新。
前言
React 是一個(gè)十分龐大的庫(kù),由于要同時(shí)考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級(jí)非常深,閱讀其源碼是一個(gè)非常艱辛的過(guò)程... 摘要:的做法比較簡(jiǎn)單,它會(huì)先刪除整個(gè)子樹(shù),然后再重新創(chuàng)建一遍。同樣道理,當(dāng)節(jié)點(diǎn)改為節(jié)點(diǎn)時(shí),整棵子樹(shù)也會(huì)被刪掉,節(jié)點(diǎn)會(huì)重新創(chuàng)建。更新為和中較大的。到此為止,整個(gè)源碼解讀系列先告一段落了,后會(huì)有期。
歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo);
一、前言
React 是一個(gè)十分龐大的庫(kù),由于要同時(shí)考慮...
當(dāng)開(kāi)發(fā)者使用React時(shí),此時(shí)的
Virtual DOM對(duì)象,只不過(guò)標(biāo)簽名稱相同罷了.
_createOpenTagMarkupAndPutListeners: function(transaction, props) {
var ret = "<" + this._currentElement.type;
// 拼湊出屬性
for (var propKey in props) {
var propValue = props[propKey];
if (registrationNameModules.hasOwnProperty(propKey)) {
// 針對(duì)當(dāng)前的節(jié)點(diǎn)添加事件代理
if (propValue) {
enqueuePutListener(this, propKey, propValue, transaction);
}
} else {
if (propKey === STYLE) {
if (propValue) {
// 合并樣式
propValue = this._previousStyleCopy = Object.assign({}, props.style);
}
propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this);
}
// 創(chuàng)建屬性標(biāo)識(shí)
var markup = null;
if (this._tag != null && isCustomComponent(this._tag, props)) {
markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
}
if (markup) {
ret += " " + markup;
}
}
}
// 對(duì)于靜態(tài)頁(yè)面,不需要設(shè)置react-id,這樣可以節(jié)省大量字節(jié)
if (transaction.renderToStaticMarkup) {
return ret;
}
// 設(shè)置reactid
if (!this._nativeParent) {
ret += " " + DOMPropertyOperations.createMarkupForRoot();
}
ret += " " + DOMPropertyOperations.createMarkupForID(this._domID);
return ret;
}
相關(guān)文章
解讀React源碼(一):初探React源碼
React 源碼深度解讀(一):首次DOM元素渲染 - Part 1
React 源碼深度解讀(二):首次 DOM 元素渲染 - Part 2
React 源碼深度解讀(九):?jiǎn)蝹€(gè)元素更新
React 源碼深度解讀(十):Diff 算法詳解
發(fā)表評(píng)論
0條評(píng)論
閱讀 1793·2023-04-25 15:51
閱讀 2503·2021-10-13 09:40
閱讀 2137·2021-09-23 11:22
閱讀 3248·2019-08-30 14:16
閱讀 2657·2019-08-26 13:35
閱讀 1853·2019-08-26 13:31
閱讀 880·2019-08-26 11:39
閱讀 2739·2019-08-26 10:33