欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談從React渲染流程分析Diff算法

 更新時(shí)間:2018年09月08日 10:32:06   作者:keywords  
這篇文章主要介紹了淺談從React渲染流程分析Diff算法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

React中最神奇的部分莫過(guò)于虛擬DOM,以及其高效的Diff算法。這讓我們可以無(wú)需擔(dān)心性能問(wèn)題而”毫無(wú)顧忌”的隨時(shí)“刷新”整個(gè)頁(yè)面,由虛擬DOM來(lái)確保只對(duì)界面上真正變化的部分進(jìn)行實(shí)際的DOM操作。React在這一部分已經(jīng)做到足夠透明,在實(shí)際開(kāi)發(fā)中我們基本無(wú)需關(guān)心虛擬DOM是如何運(yùn)作的。然而,理解其運(yùn)行機(jī)制不僅有助于更好的理解React組件的生命周期,而且對(duì)于進(jìn)一步優(yōu)化React程序也會(huì)有很大幫助。

1、什么是虛擬DOM

在React中,render執(zhí)行的結(jié)果得到的并不是真正的DOM節(jié)點(diǎn),結(jié)果僅僅是輕量級(jí)的JavaScript對(duì)象,我們稱之為virtual DOM。

簡(jiǎn)單的說(shuō),其實(shí)所謂的virtual DOM就是JavaScript對(duì)象到Html DOM節(jié)點(diǎn)的映射;即使用JavaScript對(duì)象將Html結(jié)構(gòu)表示出來(lái),而這個(gè)對(duì)象就是virtual DOM。

eg:

Html:

<ul id='list'>
 <li class='item'>Item 1</li>
 <li class='item'>Item 2</li>
</ul>

JavaScript對(duì)象表示(virtual DOM)

{
 tagName: 'ul',
 props: {
 id: 'list'
 },
 children: [
 {tagName: 'li', props: {class: 'item'}, children: ["Item 1"]},
 {tagName: 'li', props: {class: 'item'}, children: ["Item 2"]},
 ]
}

2、什么時(shí)候會(huì)生成到virtual DOM

React生命周期擁有裝載、更新、卸載的三個(gè)階段;附上一張React生命周期圖

前面提到:render執(zhí)行的結(jié)果得到的并不是真正的DOM節(jié)點(diǎn),結(jié)果僅僅是輕量級(jí)的JavaScript對(duì)象,即在render函數(shù)調(diào)用時(shí)將會(huì)創(chuàng)建出虛擬DOM;

class Tab extends React.Component {
 render() {
 React.createElement(
  'p',
  { className: 'class'},
  'Hello React'
 )
 }
}

通過(guò)React.createElemen創(chuàng)建出虛擬DOM,而該函數(shù)只在Render函數(shù)中調(diào)用,所以在React裝載和更新的過(guò)程中才會(huì)有虛擬DOM的生成;至于掛載到真實(shí)DOM自然而然是ReactDom.render函數(shù)啦。

3、virtual DOM如何實(shí)現(xiàn)

實(shí)現(xiàn)其實(shí)很簡(jiǎn)單,主要是定義一個(gè)函數(shù)并把我們傳進(jìn)去的參數(shù)組成一個(gè)React元素對(duì)象,而type就是我們傳進(jìn)去的組件類型,可以是一個(gè)類、函數(shù)或字符串(如'div')

React大致源碼:

function createElement(type, config, children) {
 let propName;

 const props = {};

 let key = null;
 let ref = null;
 let self = null;
 let source = null;

 if (config != null) {
 if (hasValidRef(config)) {
 // 如果有ref,將它取出來(lái)
 ref = config.ref;
 }
 if (hasValidKey(config)) {
 // 如果有key,將它取出來(lái)
 key = '' + config.key;
 }

 self = config.__self === undefined ? null : config.__self;
 source = config.__source === undefined ? null : config.__source;
 
 for (propName in config) {
 if (
 hasOwnProperty.call(config, propName) &&
 !RESERVED_PROPS.hasOwnProperty(propName)
 ) {
 // 將除ref,key等這些特殊的屬性放到新的props對(duì)象里
 props[propName] = config[propName];
 }
 }
 }

 // 獲取子元素
 const childrenLength = arguments.length - 2;
 if (childrenLength === 1) {
 props.children = children;
 } else if (childrenLength > 1) {
 const childArray = Array(childrenLength);
 for (let i = 0; i < childrenLength; i++) {
 childArray[i] = arguments[i + 2];
 }
 props.children = childArray;
 }

 // 添加默認(rèn)props
 if (type && type.defaultProps) {
 const defaultProps = type.defaultProps;
 for (propName in defaultProps) {
 if (props[propName] === undefined) {
 props[propName] = defaultProps[propName];
 }
 }
 }
 
 return ReactElement(
 type,
 key,
 ref,
 self,
 source,
 ReactCurrentOwner.current,
 props,
 );
}

const ReactElement = function(type, key, ref, self, source, owner, props) {
 // 最終得到的React元素
 const element = {
 // This tag allows us to uniquely identify this as a React Element
 $$typeof: REACT_ELEMENT_TYPE,

 // Built-in properties that belong on the element
 type: type,
 key: key,
 ref: ref,
 props: props,

 // Record the component responsible for creating this element.
 _owner: owner,
 };

 return element;
};

打印出組件:

4、為什么需要使用virtual DOM

DOM管理歷史階段:

  1. JS 或者 jQuery 操作 DOM: 當(dāng)應(yīng)用程序越來(lái)越復(fù)雜,需要在JS里面維護(hù)的字段也越來(lái)越多,需要監(jiān)聽(tīng)事件和在事件回調(diào)用更新頁(yè)面的DOM操作也越來(lái)越多,應(yīng)用程序會(huì)變得非常難維護(hù)。
  2. 后來(lái)產(chǎn)出 MVC、MVP 的架構(gòu)模式,期望從代碼組織方式來(lái)降低維護(hù)難度。但是 MVC 架構(gòu)并沒(méi)辦法減少維護(hù)的狀態(tài),也沒(méi)有降低狀態(tài)更新時(shí)需要對(duì)頁(yè)面的更新操作,你需要操作的DOM還是需要操作,只是換了個(gè)地方。
  3. 既然狀態(tài)改變了要操作相應(yīng)的DOM元素,為什么不做一個(gè)東西讓視圖和狀態(tài)進(jìn)行綁定,狀態(tài)變更了視圖自動(dòng)變更。這就是后來(lái)人們想出了 MVVM 模式,只要在模版中聲明視圖組件是和什么狀態(tài)進(jìn)行綁定的,雙向綁定引擎就會(huì)在狀態(tài)更新的時(shí)候自動(dòng)更新視圖;
  4. 但MVVM雙向數(shù)據(jù)綁定并不是唯一的辦法,還有一個(gè)非常直觀的方法:一旦狀態(tài)發(fā)生了變化,就用模版引擎重新渲染整個(gè)視圖,然后用新的視圖更換掉舊的視圖。

React采用的就是第四種模式;但是我們都知道對(duì)于操作DOM成本太高,而相對(duì)操作JavaScript就快速多了,而Html DOM可以很簡(jiǎn)單的用JavaScript對(duì)象表示出來(lái)(Virtual DOM就這樣誕生了)

這樣的做法會(huì)導(dǎo)致很多的問(wèn)題,最大的問(wèn)題就是這樣做會(huì)很慢,因?yàn)榧词挂粋€(gè)小小的狀態(tài)變更都要重新構(gòu)造整棵 DOM,性價(jià)比太低;而React Virtual DOM在狀態(tài)更新過(guò)程加了一些特別的操作來(lái)避免整棵 DOM 樹(shù)變更(它就是接下來(lái)的Diff算法)。

接下來(lái)的Diff算法即將更新,敬請(qǐng)期待~~~

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • react.js框架Redux基礎(chǔ)案例詳解

    react.js框架Redux基礎(chǔ)案例詳解

    這篇文章主要介紹了react.js框架Redux基礎(chǔ)案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 解決react-connect中使用forwardRef遇到的問(wèn)題

    解決react-connect中使用forwardRef遇到的問(wèn)題

    這篇文章主要介紹了解決react-connect中使用forwardRef遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 深入理解React調(diào)度(Scheduler)原理

    深入理解React調(diào)度(Scheduler)原理

    本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • pubsub-js在react中的使用教程

    pubsub-js在react中的使用教程

    pubsub-js?是一個(gè)用于實(shí)現(xiàn)發(fā)布-訂閱模式的 JavaScript 庫(kù),可以用于不同組件之間的通信,在 React 中,可以使用?pubsub-js?來(lái)實(shí)現(xiàn)組件之間的通信,本篇文章給大家講解pubsub-js在react中的使用,感興趣的朋友一起看看吧
    2023-10-10
  • 示例詳解react中useState的用法

    示例詳解react中useState的用法

    useState 通過(guò)在函數(shù)組件里調(diào)用它來(lái)給組件添加一些內(nèi)部 state,React 會(huì)在重復(fù)渲染時(shí)保留這個(gè) state,接下來(lái)通過(guò)一個(gè)示例來(lái)看看怎么使用 useState吧
    2021-06-06
  • 深入掌握 react的 setState的工作機(jī)制

    深入掌握 react的 setState的工作機(jī)制

    本篇文章主要介紹了深入掌握 react的 setState的工作機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • React路由攔截模式及withRouter示例詳解

    React路由攔截模式及withRouter示例詳解

    這篇文章主要為大家介紹了React路由攔截模式及withRouter示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • React state狀態(tài)屬性詳細(xì)講解

    React state狀態(tài)屬性詳細(xì)講解

    React將組件(component)看成一個(gè)狀態(tài)機(jī)(State Machines),通過(guò)其內(nèi)部自定義的狀態(tài)(State)和生命周期(Lifecycle)實(shí)現(xiàn)并與用戶交互,維持組件的不同狀態(tài)
    2022-09-09
  • D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的散點(diǎn)圖 (V3版本)

    D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的散點(diǎn)圖 (V3版本)

    散點(diǎn)圖(Scatter Chart),通常是一橫一豎兩個(gè)坐標(biāo)軸,數(shù)據(jù)是一組二維坐標(biāo),分別對(duì)應(yīng)兩個(gè)坐標(biāo)軸,與坐標(biāo)軸對(duì)應(yīng)的地方打上點(diǎn)。由此可以猜到,需要的元素包括circle(圓)和axis(坐標(biāo)軸),接下來(lái)通過(guò)本文大家分享D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的散點(diǎn)圖 (V3版本) ,一起看看
    2019-05-05
  • 詳解React之key的使用和實(shí)踐

    詳解React之key的使用和實(shí)踐

    這篇文章主要介紹了詳解React之key的使用和實(shí)踐,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論