成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從頭實現(xiàn)一個簡易版React(一)

meislzhua / 3106人閱讀

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

寫在開頭

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

進入正題

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

Virtual DOM的實現(xiàn)

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

/**
 * @param type :代表當前的節(jié)點屬性
 * @param key :用來標識element,用于優(yōu)化以后的更新
 * @param props:節(jié)點的屬性
 */
function VDom(type, key, props) {
  this.type = type
  this.key = key
  this.props = props
}
// 代碼地址:src/react/reactElement.js  

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

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

  config = config || {}
  // 獲取key,用來標識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  

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

ReactComponent的實現(xiàn)

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

文本類型

原生DOM類型

自定義類型

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

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

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

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

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

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

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

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

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

class App extends React.Component {
}

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

這段代碼來充當渲染的入口,下面我們來實現(xiàn)這個入口,(為了方便說明,我把render方法也放在了React對象中)

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

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

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

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

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

// component工廠,用來返回一個component實例
function instantiateReactComponent(node) {
  // 文本節(jié)點的情況
  if (typeof node === "string" || typeof node === "number") {
    return new ReactTextComponent(node)
  }

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

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

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

總結(jié)

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

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

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93118.html

相關(guān)文章

  • 從頭實現(xiàn)簡易React(二)

    摘要:寫在開頭從頭實現(xiàn)一個簡易版一地址上一節(jié),我們詳細介紹了實現(xiàn)一個簡易的思路以及整體的結(jié)構(gòu),但是對于渲染和更新的原理,卻還沒有提及,因此,本節(jié)我們將重點放在的渲染上。 寫在開頭 從頭實現(xiàn)一個簡易版React(一)地址:https://segmentfault.com/a/11...上一節(jié),我們詳細介紹了實現(xiàn)一個簡易React的思路以及整體的結(jié)構(gòu),但是對于渲染和更新的原理,卻還沒有提及,因此...

    vvpvvp 評論0 收藏0
  • 從頭實現(xiàn)簡易React(三)

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

    yvonne 評論0 收藏0
  • 基于react native的登錄界面demo 超簡易教程 redux

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

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

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

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

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

    LeexMuller 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<