爲何要實現一個React?若是你進來看了這篇文章,相信你個人想法是一致的,爲了更好的理解和使用React。這一篇是這個文章系列的第一篇,主要說下實現React以前須要掌握和明白的地方,不僅僅是介紹,請耐心看完。這個系列須要足夠的耐心去看,靜下心來纔能有更大的收穫。本系列文章參考dialact系列文章,你能夠直接去看dialact,它也足夠精簡。這個系列中我會調整部分結構來幫助理解。html
在React的實現中,有幾種寫法須要瞭解。node
var dom = document.getElmentById('root');
dom['className'] = 'container'
dom['style'] = 'background-color: red';
複製代碼
咱們這裏使用直接賦值的方法,而不是使用setAttribute
來給dom添加Attribute,是爲了保證只有有效的Attribute
才能被賦值。這裏涉及到attribute
和property
的區別。react
attribute
描述xml中的附加值如git
<apple name='apple'></apple>
複製代碼
這裏的name
就是attribute
,property
在js中描述的是對象的屬性如github
var person = { name: 'chris' }
複製代碼
這裏的name
是property
。算法
對於dom元素來講,它是一個HTMLElement
類型的對象,它有不少property
,在其property
中有一個attributes
屬性,該屬性是NameNodeMap
類型,用來存儲html展現的attributes
。npm
當咱們使用setAttribute
函數時,會直接爲attributes
賦值,不論其名稱如何。而若是咱們使用dom['property'] = value
的形式的時候,它會根據名稱尋找和attributes
之間的對應關係,若是有對應則在賦值的同時爲dom
添加attribute
,若是沒有則只添加property
而不會添加attribute
。bash
property
和attribute
之間的對象關係根據不一樣的元素類型來肯定,同時對應名稱也不是必定相同,如babel
// 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語法app
<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
。
因爲操做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系列列表: