React從零實現-介紹和準備

Xiaowei發表於2018-07-24

logo-og

為什麼要實現一個React?如果你進來看了這篇文章,相信你我的想法是一致的,為了更好的理解和使用React。這一篇是這個文章系列的第一篇,主要說下實現React之前需要掌握和明白的地方,不單單是介紹,請耐心看完。這個系列需要足夠的耐心去看,靜下心來才能有更大的收穫。本系列文章參考dialact系列文章,你可以直接去看dialact,它也足夠精簡。這個系列中我會調整部分結構來幫助理解。

預備知識

在React的實現中,有幾種寫法需要了解。

為dom元素新增Attribute

var dom = document.getElmentById('root');
dom['className'] = 'container'
dom['style'] = 'background-color: red';
複製程式碼

我們這裡使用直接賦值的方法,而不是使用setAttribute來給dom新增Attribute,是為了保證只有有效的Attribute才能被賦值。這裡涉及到attributeproperty的區別。

attribute和property的區別

attribute描述xml中的附加值如

<apple name='apple'></apple>
複製程式碼

這裡的name就是attributeproperty在js中描述的是物件的屬性如

var person = { name: 'chris' }
複製程式碼

這裡的nameproperty

對於dom元素來說,它是一個HTMLElement型別的物件,它有很多property,在其property中有一個attributes屬性,該屬性是NameNodeMap型別,用來儲存html展示的attributes

當我們使用setAttribute函式時,會直接為attributes賦值,不論其名稱如何。而如果我們使用dom['property'] = value的形式的時候,它會根據名稱尋找和attributes之間的對應關係,如果有對應則在賦值的同時為dom新增attribute,如果沒有則只新增property而不會新增attribute

propertyattribute之間的物件關係根據不同的元素型別來確定,同時對應名稱也不是一定相同,如

// property => attribute
style => style
className => class
htmlFor => html
複製程式碼

其他要用到的方法

// 為元素繫結事件
dom.addEventListener('click', function() {});

// 為文字節點賦值
dom['nodeValue'] = value;

// 尋找節點
var dom = document.getElementById('root');

// 建立節點
var dom = document.createElement('div');

// 建立文字節點
var dom = document.createTextNode('');
複製程式碼

jsx

jsx的本質是一個語法糖,例如有如下jsx語法

<div className="container">
  <h1>hello world</h1>
</div>
複製程式碼

在React中會被解析成如下形式:

React.createElement(
  'div',
  { className: 'container' },
  React.createElement(
    h1,
    null,
    "hello world"
  )
)
複製程式碼

這個轉換我們可以藉助babel-plugin-transform-react-jsx來幫助我們實現,我們所需要做的就是實現React.createElement

diff

由於操作dom要付出的代價很大,React最大限度的來利用已經生成的dom,避免重複渲染。React中用到了虛擬dom的概念,它其實就是一個物件,類似於我們上面jsx中寫到的

{
  type: 'h1',
  children: ['hello world']
}
複製程式碼

實際的React中更加複雜,配合diff演算法可以減少dom操作。傳統比較兩棵樹的演算法是O(n^3),React有兩個假設:

  • 不同型別的節點會產生不同的樹
  • 開發者能夠通過賦值key屬性來區分列表中不同的節點

在這兩個假設的基礎上,React只需要比較兩棵dom樹中同一層對應的節點就可以,將演算法複雜度降低到O(n),同時能覆蓋到絕大部分的情況,這種diff演算法在React中被稱作Reconciliation

下一篇,我們開始實現我們自己的React,先進行節點建立和渲染。接下來我會持續更新,這是github原文地址,歡迎star,歡迎watch。

實現React系列列表:

相關文章