亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從頭實(shí)現(xiàn)一個(gè)簡(jiǎn)易版React(一)

meislzhua / 3143人閱讀

摘要:既然看不懂,那就看看社區(qū)前輩們寫(xiě)的一些源碼分析文章以及實(shí)現(xiàn)思路吧,又這么過(guò)了幾天,總算是摸清點(diǎn)思路,于是在參考了前輩們的基礎(chǔ)上,實(shí)現(xiàn)了一個(gè)簡(jiǎn)易版的。總結(jié)以上就是實(shí)現(xiàn)一個(gè)的總體思路,下節(jié)我們重點(diǎn)放在不同的上。

寫(xiě)在開(kāi)頭

工作中使用react也很長(zhǎng)一段時(shí)間了,雖然對(duì)它的用法,原理有了一定的了解,但是總感覺(jué)停留在表面。本著知其然知其所以然的態(tài)度,我試著去看了react源碼,幾天下來(lái),發(fā)現(xiàn)并不能看懂,反而更加云里霧里了- -!。既然看不懂,那就看看社區(qū)前輩們寫(xiě)的一些源碼分析文章以及實(shí)現(xiàn)思路吧,又這么過(guò)了幾天,總算是摸清點(diǎn)思路,于是在參考了前輩們的基礎(chǔ)上,實(shí)現(xiàn)了一個(gè)簡(jiǎn)易版的react。
這個(gè)系列我打算分為3節(jié),第一節(jié)介紹下實(shí)現(xiàn)的思路以及結(jié)構(gòu),第二節(jié)講渲染,第三節(jié)講更新。

進(jìn)入正題

眾所周知,react的核心是Virtual DOM,所以,我們的思路也是圍繞著Virtual DOM展開(kāi),包含Virtual DOM模型的建立,生命周期的管理,對(duì)比差異的diff算法,將Virtual DOM轉(zhuǎn)化為原生DOM并展示的patch方法等,setState異步機(jī)制以及react合成事件由于還沒(méi)有研究到,暫時(shí)先忽略,事件處理跟某位前輩的思路一樣,也是使用jquery事件代替,這里我們主要以實(shí)現(xiàn)渲染,更新為主,相信你在看完這個(gè)系列后,能對(duì)react的運(yùn)行原理有一定理解。
項(xiàng)目地址:https://github.com/LuSuguru/f...,以下的所有代碼都是通過(guò)es6編寫(xiě),切勿用在生產(chǎn)環(huán)境。

Virtual DOM的實(shí)現(xiàn)

React的一切都基于Virtual DOM,我們第一步自然先實(shí)現(xiàn)它,如下:

/**
 * @param type :代表當(dāng)前的節(jié)點(diǎn)屬性
 * @param key :用來(lái)標(biāo)識(shí)element,用于優(yōu)化以后的更新
 * @param props:節(jié)點(diǎn)的屬性
 */
function VDom(type, key, props) {
  this.type = type
  this.key = key
  this.props = props
}
// 代碼地址:src/react/reactElement.js  

實(shí)現(xiàn)了vDom后,理所需要一個(gè)方法來(lái)將我們寫(xiě)的元素轉(zhuǎn)化為vDom。一般我們都是JSX來(lái)創(chuàng)建元素的,但它只不過(guò)是React.createElment的語(yǔ)法糖。所以,接下來(lái),我們要實(shí)現(xiàn)的就是createElement方法:

function createElement(type, config, ...children) {
  const props = {}

  config = config || {}
  // 獲取key,用來(lái)標(biāo)識(shí)element,方便以后高效的更新
  const { key = null } = config
 
  let propName = ""

  // 復(fù)制config里的內(nèi)容到props
  for (propName in config) {
    if (config.hasOwnProperty(propName) && propName !== "key") {
      props[propName] = config[propName]
    }
  }

  // 轉(zhuǎn)化children
  if (children.length === 1 && Array.isArray(children[0])) {
    props.children = children[0]
  } else {
    props.children = children
  }

  return new VDom(type, key, props)
}
// 代碼地址:src/react/reactElement.js  

這段代碼也非常簡(jiǎn)單,根據(jù)我們傳入的參數(shù),生成對(duì)應(yīng)的vDom

ReactComponent的實(shí)現(xiàn)

我們所創(chuàng)建的VDom類型分為3種:

文本類型

原生DOM類型

自定義類型

不同的類型,肯定有不同的渲染和更新邏輯,我們把這些邏輯與vDom一起,封裝成對(duì)應(yīng)的ReactComponent類,通過(guò)ReactComponent類控制vDom,這里我把它們命名為ReactTextComponent,ReactDomComponent,ReactCompositeComponent,分別對(duì)應(yīng)三種類型。
首先是基類ReactComponet:

// component基類,用來(lái)處理不同的虛擬dom更新,渲染
class Component {
  constructor(element) {
    this._vDom = element
    // 用來(lái)標(biāo)識(shí)當(dāng)前component
    this._rootNodeId = null
  }
}
// 代碼地址:src/react/component/ReactComponent.js  

接著再讓不同類型的component繼承這個(gè)基類,每種component類型都有mount和update兩個(gè)方法,用來(lái)執(zhí)行渲染和更新

class ReactDomComponent extends ReactComponent {
    // 渲染
  mountComponent() {}

  // 更新
  updateComponent() {}
}
class ReactCompositeComponent extends ReactComponent {
    // 渲染
  mountComponent() {}

  // 更新
  updateComponent() {}
}
class ReactTextComponent extends ReactComponent {
    // 渲染
  mountComponent() {}

  // 更新
  updateComponent() {}
}
入口的實(shí)現(xiàn)

實(shí)現(xiàn)了ReactComponent后,我們自然需要一個(gè)入口去得到ReactComponent并調(diào)用它的mount。在使用React時(shí),通常都是通過(guò)

import React from "react"
import ReactDOM from "react-dom"

class App extends React.Component {
}

ReactDOM.render(, document.getElementById("root"))

這段代碼來(lái)充當(dāng)渲染的入口,下面我們來(lái)實(shí)現(xiàn)這個(gè)入口,(為了方便說(shuō)明,我把render方法也放在了React對(duì)象中)

import Component from "./Component"
import createElement from "./ReactElement"
import instantiateReactComponent from "./component/util"
import $ from "jquery"

const React = {
  nextReactRootIndex: 0, // 標(biāo)識(shí)id,確定每個(gè)vDom的唯一性
  Component, // 所有自定義組件的父類
  createElement, // 創(chuàng)建vdom

  render(vDom, container) { // 入口
    var componentInstance = instantiateReactComponent(vDom) //通過(guò)vDom生成Component
    var markup = componentInstance.mountComponent(this.nextReactRootIndex++)

    container.innerHTML = markup
    $(document).trigger("mountReady")
  }
}
// 代碼地址:src/react/index.js  

由于渲染和更新都已經(jīng)封裝在不同的ReactComponent里,所以,這里也需要一個(gè)方法,根據(jù)不同的vDom類型生成對(duì)應(yīng)的ReactComponent,下面我們就來(lái)實(shí)現(xiàn)這個(gè)方法:

// component工廠,用來(lái)返回一個(gè)component實(shí)例
function instantiateReactComponent(node) {
  // 文本節(jié)點(diǎn)的情況
  if (typeof node === "string" || typeof node === "number") {
    return new ReactTextComponent(node)
  }

  // 瀏覽器默認(rèn)節(jié)點(diǎn)的情況
  if (typeof node === "object" && typeof node.type === "string") {
    return new ReactDomComponent(node)
  }

  // 自定義的元素節(jié)點(diǎn)
  if (typeof node === "object" && typeof node.type === "function") {
    return new ReactCompositeComponent(node)
  }
}

然后再調(diào)用入口ReactComponent的mount方法,獲取渲染內(nèi)容,再將其渲染出來(lái)就行。

總結(jié)

以上就是實(shí)現(xiàn)一個(gè)react的總體思路,下節(jié)我們重點(diǎn)放在不同ReactComponet的mount上。
下一節(jié)地址:https://segmentfault.com/a/11...

參考資料,感謝幾位前輩的分享:
https://www.cnblogs.com/sven3...
https://github.com/purplebamb...
陳屹 《深入React技術(shù)?!?/p>

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93118.html

相關(guān)文章

  • 從頭實(shí)現(xiàn)個(gè)簡(jiǎn)易React(二)

    摘要:寫(xiě)在開(kāi)頭從頭實(shí)現(xiàn)一個(gè)簡(jiǎn)易版一地址上一節(jié),我們?cè)敿?xì)介紹了實(shí)現(xiàn)一個(gè)簡(jiǎn)易的思路以及整體的結(jié)構(gòu),但是對(duì)于渲染和更新的原理,卻還沒(méi)有提及,因此,本節(jié)我們將重點(diǎn)放在的渲染上。 寫(xiě)在開(kāi)頭 從頭實(shí)現(xiàn)一個(gè)簡(jiǎn)易版React(一)地址:https://segmentfault.com/a/11...上一節(jié),我們?cè)敿?xì)介紹了實(shí)現(xiàn)一個(gè)簡(jiǎn)易R(shí)eact的思路以及整體的結(jié)構(gòu),但是對(duì)于渲染和更新的原理,卻還沒(méi)有提及,因此...

    vvpvvp 評(píng)論0 收藏0
  • 從頭實(shí)現(xiàn)個(gè)簡(jiǎn)易React(三)

    摘要:寫(xiě)在開(kāi)頭從頭實(shí)現(xiàn)一個(gè)簡(jiǎn)易版二地址在上一節(jié),我們的已經(jīng)具備了渲染功能。參考資料,感謝幾位前輩的分享陳屹深入技術(shù)棧 寫(xiě)在開(kāi)頭 從頭實(shí)現(xiàn)一個(gè)簡(jiǎn)易版React(二)地址:https://segmentfault.com/a/11...在上一節(jié),我們的react已經(jīng)具備了渲染功能。在這一節(jié)我們將著重實(shí)現(xiàn)它的更新,說(shuō)到更新,大家可能都會(huì)想到React的diff算法,它可以說(shuō)是React性能高效的保...

    yvonne 評(píng)論0 收藏0
  • 基于react native的登錄界面demo 超簡(jiǎn)易教程 redux

    摘要:登錄視圖登陸失敗用戶名或密碼不能為空彈出提示框成功是點(diǎn)擊登錄按鈕后調(diào)用的函數(shù),這里的功能比較簡(jiǎn)單。通過(guò)把發(fā)出去密碼登錄聲明組件需要整個(gè)中的哪一部分?jǐn)?shù)據(jù)作為自己的將和組件聯(lián)系在一起編寫(xiě)是負(fù)責(zé)生成的,所以在大項(xiàng)目中還會(huì)用到合并。 本豬說(shuō) 本豬豬剛學(xué)react,也剛看RN,就叫寫(xiě)這個(gè),苦不堪言,搭環(huán)境就搭了好久??淳W(wǎng)上教程也是改了好多小地方才寫(xiě)完了。本著雷鋒精神手把手教你寫(xiě)(假的)。 sho...

    scq000 評(píng)論0 收藏0
  • 借助Docker和Kodexplorer實(shí)現(xiàn)簡(jiǎn)易化部署Discuz類論壇網(wǎng)站

    摘要:在主機(jī)輸入框中輸入自己的云服務(wù)器分配的公網(wǎng),其他設(shè)置不變,點(diǎn)擊連接之后會(huì)出現(xiàn)安全警告,如果是在自己的電腦上操作的話,接受并保存即可。 基于DiscuzX系列構(gòu)建的論壇可以說(shuō)是大家在日常瀏覽各類BBS網(wǎng)站中接觸最多的論壇類型了。本教程旨在引導(dǎo)讀者通過(guò)簡(jiǎn)單明確的一些步驟就打造出自己的論壇網(wǎng)站,做一個(gè)實(shí)實(shí)在在的站長(zhǎng)。 工具/原料 騰訊云服務(wù)器 CentOS 7.2 64位;遠(yuǎn)程控制程序 ...

    happen 評(píng)論0 收藏0
  • 借助Docker和Kodexplorer實(shí)現(xiàn)簡(jiǎn)易化部署Discuz類論壇網(wǎng)站

    摘要:在主機(jī)輸入框中輸入自己的云服務(wù)器分配的公網(wǎng),其他設(shè)置不變,點(diǎn)擊連接之后會(huì)出現(xiàn)安全警告,如果是在自己的電腦上操作的話,接受并保存即可。 基于DiscuzX系列構(gòu)建的論壇可以說(shuō)是大家在日常瀏覽各類BBS網(wǎng)站中接觸最多的論壇類型了。本教程旨在引導(dǎo)讀者通過(guò)簡(jiǎn)單明確的一些步驟就打造出自己的論壇網(wǎng)站,做一個(gè)實(shí)實(shí)在在的站長(zhǎng)。 工具/原料 騰訊云服務(wù)器 CentOS 7.2 64位;遠(yuǎn)程控制程序 ...

    LeexMuller 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<