1. 程式人生 > >React的思想

React的思想

creat script 調用 js計算 string 部分 底層 服務器 stat

react是什麽

react是開發出來用來促進UI交互的,創建帶有狀態的、可復用的UI組件的IU庫
react不僅可以在瀏覽器端使用,還可以在服務器端使用,還可以兩端一起使用。
react的底層概念:運用的是virtual DOM(虛擬DOM),然後根據UI組件的狀態變化,有選擇的渲染DOM的節點樹,盡可能的操作最少的DOM來更新組件。

虛擬DOM是怎麽工作的

1.在Web開發中,需要將數據的變化實時反映到UI上,就需要對DOM進行操作,但是復雜頻繁的DOM操作會產生性能瓶頸。所以DOM就引入了虛擬DOM的機制。
實際上,在React中,render方法得到的實際上不是真實的DOM節點,而僅僅是輕量級的JavaScript對象,我們稱之為虛擬DOM.

2.虛擬DOM是React的一大亮點,具有批處理(batching)和高效的Diff算法。無需擔心性能問題而毫無顧忌的隨時刷新整個頁面,由虛擬DOM來確保只對界面上真正變化的部分進行實際的DOM操作。
了解React虛擬DOM的機制就可以更好的理解React組件的生命周期,而且對於進一步優化React組件的生命周期。
如果沒有虛擬DOM,就相當於重置innerHTML,在數據變動比較大的情況下,比較合理,但是如果只有一小部分數據變化時,也要重置整個innerHTML,這就造成了很大的浪費。
兩者的比較
innerHTML: render html string + 重新創建所有的DOM元素
virtual DOM: render Virtual DOM + diff + 必要的DOM更新。

3.和DOM操作比起來,js計算還是非常便宜的。Virtual DOM + diff 顯然要比render string慢,但是後面的DOM操作就比較便宜了。
DOM完全不屬於JavaScript,也不在JavaScript引擎中,JavaScript實際上是一個獨立的引擎,而DOM其實是瀏覽器引出的一組讓JavaScript操作HTML文檔的API而已,在即時編譯的時代下,調用DOM的開銷是很大的,而Virtual DOM的執行完全都在JavaScript引擎中,不存在這個開銷。

4.React.js相對於直接操作原生DOM有很大的性能優勢,很大程度上歸功於虛擬DOM的batching和diff,batching把所有的DOM操作搜集起來,一次性提交給真實的DOM,

什麽是虛擬DOM

React中,將真實的DOM抽象成一個JavaScript對象,也就是虛擬DOM,比如構造一個虛擬的DOM.

var element = {
    element: ‘ul‘,
    props: {
        id: ‘list‘
    },
    children: [
        {element:‘li‘,props:‘li1‘,children:[‘這是第一個li‘]},
        {element:‘li‘,props:‘li2‘,children:[‘這是第二個li‘]}
    ]
}

//element.js
function Element(tagName,props,children){
    this.tagName = tagName;
    this.props = props;
    this.children = children;
}

module.exports = function(tagName,props,children){
    return new Element(tagName,props,children)
}

var el = require(‘./element‘);
var ul = el(‘ul‘,{id:‘ulist‘},[
        el(‘li‘,{id:‘list1‘},[‘1list‘]),
        el(‘li‘,{id:‘list2‘},[‘list2‘])
])
//ul只是一個JavaScript對象表示的DOM結構,頁面上並沒有這個結構,可以根據這個ul構建真正的<ul>
Element.prototype.render = function(){
    var d = document.createElement(tagName);
    //獲取props
    var props = this.props;
    for (key in props) {
        var propValue = props[key];
        d.setAttribute(key,propValue);
    }

    //獲取children
    var children = this.children || [];
    children.forEach(function(child){
      // if (child instanceof Element){
        //     tnode = child.render();
        // }
        // else{
        //     tnode = document.createTextNode(child);
        // }
        var childEl = (child instanceof Element) ? child.render():document.createTextNode(child)
        d.appendChild(childEl);
    })
    return d;
}

var ulRoot = ul.render();
document.body.appendChild(ulRoot);
//ulRoot是真正的DOM節點,把它塞入文檔中,這樣body裏面就有了真正的<ul>的DOM結構。

在React中,也有一個render函數,當React中有state轉移的過程,所以每次state有變化之後,就會觸發render函數,重新構造一個虛擬DOM樹,對比新舊DOM樹的差別,記錄下差別,然後只針對差異部分對應的真實DOM進行操作。先總結到這裏,下一篇博客,詳細講解Diff算法。

React的思想