首頁  >  文章  >  web前端  >  Diff演算法的分析:利用React渲染流程分析

Diff演算法的分析:利用React渲染流程分析

不言
不言原創
2018-09-08 15:53:431267瀏覽

本篇文章帶給大家的內容是關於Diff演算法的分析:利用React渲染流程分析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

1、什麼是虛擬DOM

在React中,render執行的結果得到的並不是真正的DOM節點,結果只是輕量級的JavaScript對象,我們稱之為virtual DOM。
  • 簡單的說,其實所謂的virtual DOM就是JavaScript物件到Html DOM節點的對應;即使用JavaScript物件將Html結構表示出來,而這個物件就是virtual DOM。

  • Html:


      
  • Item 1
  •   
  • Item 2
  • JavaScript物件表示法(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、何時會產生到virtual DOM

  • React生命週期擁有裝載、更新、卸載的三個階段;附上一張React生命週期圖

Diff演算法的分析:利用React渲染流程分析

  • 前面提到:render執行的結果得到的並不是真正的DOM節點,結果只是輕量級的JavaScript對象,也就是在render函數呼叫時將會建立出虛擬DOM;

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

Diff演算法的分析:利用React渲染流程分析

    ##透過React.createElemen創建出虛擬DOM,而該函數只在Render函數中調用,所以在React裝載和更新的過程中才會有虛擬DOM的生成;至於掛載到真實DOM自然是ReactDom.render函數啦。
  • 3、virtual DOM如何實作

Diff演算法的分析:利用React渲染流程分析#實作其實很簡單,主要是定義一個函數並把我們傳進去的參數組成一個React元素對象,而type就是我們傳進去的元件類型,可以是一個類別、函數或字串(如'p')

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,将它取出来
          ref = config.ref;
        }
        if (hasValidKey(config)) {
          //  如果有key,将它取出来
          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对象里
            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 
    列印出元件:
  1. #4、為什麼需要使用virtual DOM

  2. DOM管理歷史階段:

  • #JS 或jQuery 操作DOM:當應用程式越來越複雜,需要在JS裡面維護的欄位也越來越多,需要監聽事件和在事件回呼叫更新頁面的DOM操作也越來越多,應用程式會變得非常難維護。

  • 後來產出 MVC、MVP 的架構模式,期望從程式碼組織方式來降低維護難度。但 MVC 架構並沒辦法減少維護的狀態,也沒有降低狀態更新時需要對頁面的更新操作,你需要操作的DOM還是需要操作,只是換了個地方。

  • 既然狀態改變了要操作對應的DOM元素,為什麼不做一個東西讓視圖和狀態綁定,狀態變更了視圖自動變更。這就是後來人們想出了MVVM 模式,只要在模版中宣告視圖元件是和什麼狀態進行綁定的,雙向綁定引擎就會在狀態更新的時候自動更新視圖;


    但MVVM雙向資料綁定並不是唯一的辦法,還有一個非常直觀的方法:一旦狀態發生了變化,就用模版引擎重新渲染整個視圖,然後用新的視圖更換掉舊的視圖。


    ###React採用的就是第四種模式;但我們都知道對於操作DOM成本太高,而相對操作JavaScript就快速多了,而Html DOM可以很簡單的用JavaScript物件表示出來(Virtual DOM就這樣誕生了)############這樣的做法會導致很多的問題,最大的問題就是這樣做會很慢,因為即使一個小小的狀態變更都要重新建構整棵DOM,性價比太低;而React Virtual DOM在狀態更新過程加了一些特別的操作來避免整棵DOM 樹變更。 ############相關推薦:######################

    以上是Diff演算法的分析:利用React渲染流程分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn