wordpress自定義提醒用法百度搜索怎么優(yōu)化
摘要
在上一篇,我們實(shí)現(xiàn)了通過(guò)JSX轉(zhuǎn)換為ReactElement的方法,也看到了轉(zhuǎn)換后React元素的結(jié)構(gòu)。但是這個(gè)React元素,并不能很清楚的表達(dá)組件之間的關(guān)系,以及屬性的處理。
所以在React內(nèi)部,會(huì)將所有的React元素轉(zhuǎn)換為Filber樹。而這一章節(jié),主要就是簡(jiǎn)單描述一下FilberNode的結(jié)構(gòu)。
首先看一下一顆Filber樹是什么樣子的:
在這張圖里,出了filberRootNode,其他的節(jié)點(diǎn)都是FilberNode類型,hostRootFilber就是最外層的FilberNode。
在項(xiàng)目里面,當(dāng)我們調(diào)用 **ReactDOM.createRoot(root)**方法的時(shí)候,就會(huì)創(chuàng)建出上面的FilberRootNode和hostRootFilber。并且將二者之間的指向關(guān)系確定。
1.FilberNode
首先,說(shuō)一下一個(gè)FilberNode都具有什么屬性(這里有省略)。
【1】tag屬性
我們回到React元素,可以知道React元素的type可以是,一個(gè)div,span等,也可以是一段文本text,也可以是一個(gè)函數(shù)function(函數(shù)類型組件)。
在FilberNode里面,對(duì)應(yīng)的就是tag屬性,這里我們定義好tag都可以是什么屬性:
const FunctionComponent = 'FunctionComponent'; //對(duì)應(yīng)函數(shù)
const HostRoot= 'HostRoot'; //對(duì)應(yīng)hostRootFilber
const HostComponent= 'HostComponent'; //對(duì)應(yīng)div
const HostText = 'HostText'; //對(duì)應(yīng)文本節(jié)點(diǎn)
這里面多了一個(gè)HostRoot類型,對(duì)應(yīng)的是最外層FilberNode(也就是HostRootFilber)的tag。
【2】key屬性
對(duì)應(yīng)的就是ReactElement中的key。
【3】stateNode屬性
這個(gè)屬性就比較重要了,我們思考一下,不管React內(nèi)部怎么做,最終的結(jié)果一定是生成真實(shí)的DOM。
而這個(gè)屬性就是保存每個(gè)FilberNode的真實(shí)DOM。
hostRootFilber的stateNode指向最外面的filberRootNode。
【4】type屬性
對(duì)應(yīng)的就是ReactElement中的type。
【5】ref屬性
對(duì)應(yīng)的就是ReactElement的ref屬性
【6】return , sibling, child,index屬性
前三個(gè)屬性,分表代表FilberNode的父節(jié)點(diǎn),兄弟節(jié)點(diǎn),子節(jié)點(diǎn)。通過(guò)這三個(gè)屬性來(lái)確定整顆Filber樹的結(jié)構(gòu)。
index屬性代表的就是,同級(jí)節(jié)點(diǎn)的位置。例如一個(gè)父節(jié)點(diǎn)下面有很多子節(jié)點(diǎn),index就代表它們的索引。
【7】alternate屬性
在React內(nèi)部,會(huì)維護(hù)兩棵Filber樹,current樹是用來(lái)渲染真實(shí)DOM,而B樹是在更新時(shí),通過(guò)計(jì)算生成的新的Filber樹。每次更新都會(huì)用新的Filber樹替換current樹,成為新的current樹。
所以每個(gè)FilberNode都有一個(gè)alternate屬性,用來(lái)指向另一棵樹的對(duì)應(yīng)節(jié)點(diǎn)。
【8】pendingProps屬性
用來(lái)表示FilberNode初始的props值
【9】memoizedProps屬性
用來(lái)表示更新后FilberNode的props值
【10】memoizedState屬性
和更新相關(guān)的屬性。
目前我們先準(zhǔn)備這些屬性,等后面如果有需要了再加,現(xiàn)在我們實(shí)現(xiàn)FilberNode類:
export class FilberNode {constructor(tag, pendingProps, key) {this.tag = tag;this.key = key;this.stateNode = null;this.type = null;this.return = null;this.sibling = null;this.child = null;this.index = 0;this.ref = null;this.pendingProps = pendingProps;this.memoizedProps = null;this.memoizedState = null;this.alternate = null;}
}
2.FilberRootNode
我們最開始說(shuō)過(guò),FilberRootNode并非是FilberNode。它有著自己的數(shù)據(jù)結(jié)構(gòu),現(xiàn)在我們說(shuō)一下FilberRootNode具有的屬性:
【1】container屬性
對(duì)應(yīng)的就是掛載的React元素,例如 項(xiàng)目中的App 。
【2】current屬性
指向最外層的FilberNode,也就是hostRootFilber。而hostRootFilber的stateNode指向FilberROOtNode。
【3】finishWork屬性
該屬性對(duì)應(yīng)的是已經(jīng)處理完后的最外層的FilberNode。
現(xiàn)在我們實(shí)現(xiàn)對(duì)應(yīng)的FilberRootNode類:
export class FilberRootNode {constructor(container, hostRootFilber) {this.container = container;this.current = hostRootFilber;hostRootFilber.stateNode = this;this.finishedWork = null;}
}
它的構(gòu)造函數(shù)接受兩個(gè)參數(shù),分別對(duì)應(yīng)的就是hostFilberRoot以及App。在構(gòu)造函數(shù)中,表明自身和hostFilberRoot之間的關(guān)系。
3.定義ReactDOM
現(xiàn)在我們已經(jīng)有了FilberNode和FilberRootNode的數(shù)據(jù)結(jié)構(gòu)?,F(xiàn)在我們來(lái)回想一下我們?cè)陧?xiàng)目中是怎么使用ReactDOM的。
const root = document.getElementById(‘root’)
ReactDOM.createRoot(root).render()
也就是我們要實(shí)現(xiàn)的ReactDOM中,要有createRoot方法,同時(shí)該方法返回一個(gè)render方法:
function createRoot() {return {render() {}}
}const ReactDOM = {createRoot
}export default ReactDOM
4.實(shí)現(xiàn)createRoot方法
這一篇文章只是為了定義好開頭,所以我們只實(shí)現(xiàn)基本的結(jié)構(gòu)。
在調(diào)用createRoot方法后,我們會(huì)創(chuàng)建FilberRootNode對(duì)象,這里面我們封裝成一個(gè)方法,
createContainer方法:
function createContainer(root) {const hostRootFilber = new FilberNode(HostRoot, {}, '')return new FilberRootNode(root, hostRootFilber);
}
5.小節(jié),測(cè)試
這一篇主要就說(shuō)這些,通過(guò)構(gòu)建filberNode和filberRootNode來(lái)表示整個(gè)Filber樹的結(jié)構(gòu)。
測(cè)試代碼:
import { FilberNode, FilberRootNode } from "./filberNode"
import {HostComponent, HostRoot, HostText, FunctionComponent} from './filberNode'function createRoot(root) {const filberRootNode = createContainer(root);console.log(filberRootNode);return {render() {}}
}function createContainer(root) {const hostRootFilber = new FilberNode(HostRoot, {}, '')return new FilberRootNode(root, hostRootFilber);
}const ReactDOM = {createRoot
}export default ReactDOM
在控制臺(tái)我們可以看到二者之間的關(guān)系: