實現乙個react系列一 JSX和虛擬DOM

2022-09-12 09:57:14 字數 2677 閱讀 8126

本文主要參考了從零開始實現乙個react和從 0 到 1 實現react

工作中經常使用react,對於react中的一些虛擬dom、生命週期、元件等概念知其然,不知其所以然。雖然知道這些怎麼用的就足夠應付大部分的工作,但是作為乙個開發者,還是要有追求的。所以有了這個系列,一步一步實現乙個簡單的react出來。

我們平時在react中寫的jsx,其實是一種語法糖,會被babel轉換成react.createelement()。我們可以在babel官網上做個實驗,看下jsx會被babel轉換成什麼。下面是個簡單的例子。

我們可以看到,jsx會被轉成react.createelement(tag, attrs, child1, child2, ...)這種形式。那我們只要裝個babel外掛程式,然後寫個createelement方法就可以處理jsx**了。

首先安裝babel模組,babel.babelrc配置如下:

]

]}

使用打包工具parcel,webpack也可以。比較懶,使用了parcel來打包**。

上面我們已經提到了jsx會被babel轉換為react.createelement(tag, attrs, child1, child2, ...)

第乙個引數:是元素的標籤名,可以是div、span等。

第二個引數:是元素的屬性名,可以是classnameonclick等。

之後的引數,是元素的子節點。

所以我們實現乙個函式createelement,接受上面的引數,然後將這些引數返回就可以了。

const createelement = (tag, attrs, ...childs) => 

}

看下效果如何。

const react = 

const title = (

hello, world!

)console.log(title)

開啟chrome的控制台,我們可以看到差不多是我們想要的。

createelement方法返回的物件就是虛擬dom,這個物件中記錄了該dom節點的所有資訊,根據這些資訊我們可以將虛擬dom轉化為真實的dom

在react中,將vdom渲染成真實的dom,我們使用的是reactdom.render,像這樣。

reactdom.render(

hello, world!

, // 這個會被轉化為vdom

document.getelementbyid('root') // 獲取根節點

)

我們可以看出,render實現的功能是將vdom轉化為真實的dom,掛載到根節點上。明白這一點,**就很好寫了。

const reactdom = 

// 將 vdom 轉換為真實 dom

const render = (vdom, root) =>

const dom = document.createelement(vdom.tag)

if (vdom.attrs)

} // 遍歷子節點

vdom.childs.foreach(child => render(child, dom))

// 將子元素掛載到其真實 dom 的父元素上

}// 設定 dom 節點屬性

const setattribute = (dom, attr, value) =>

// 處理事件

if (/on\w+/.test(attr)) else if (attr === "style" && value) else if (typeof value === "object")

}} else

}

這樣我們就將虛擬dom渲染成真實的dom,考慮到熱更新,我們需要在render之前先清除下root節點下的內容。

const reactdom = 

}

react中,jsx會被babel轉化為react.createelement(標籤、屬性、子元素1、子元素2、...)形式,該函式返回乙個物件,即虛擬dom。然後reactdom.render(),會將虛擬dom轉化為真實的dom

附上本文**位址

實現乙個react系列二 渲染元件

在上一節jsx和虛擬dom中,我們了解了react中的jsx到虛擬dom,以及如何將虛擬dom渲染成真實的dom。在這一節中,我們將會了解react中元件是如何渲染的。在react中,元件有兩種使用方法 import react from react 類定義的元件 class hello exten...

React 學習筆記(一) JSX

jsx 本質上來說,jsx只是react.createelement component,prop,children 方法的語法糖 header content 等價於 react.createelement myheader type props header content children j...

React起步與JSX(一)

react開發環境準備 官網安裝 將會為我們自動生成乙個react專案 1.專案結構 2 只要有jsx語法就要引入react包 2.react中的jsx基礎語法 1 在jsx中,可以使用html的標籤,也可以使用自定義標籤 2 在jsx中,如果要使用自己建立的元件,直接通過標籤形式使用即可 impo...