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