国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

React源碼解析18(5)------ 實(shí)現(xiàn)函數(shù)組件【修改beginWork和completeWork】

這篇具有很好參考價(jià)值的文章主要介紹了React源碼解析18(5)------ 實(shí)現(xiàn)函數(shù)組件【修改beginWork和completeWork】。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

摘要

經(jīng)過(guò)之前的幾篇文章,我們實(shí)現(xiàn)了基本的jsx,在頁(yè)面渲染的過(guò)程。但是如果是通過(guò)函數(shù)組件寫(xiě)出來(lái)的組件,還是不能渲染到頁(yè)面上的。
所以這一篇,主要是對(duì)之前寫(xiě)得方法進(jìn)行修改,從而能夠顯示函數(shù)組件,所以現(xiàn)在我們?cè)趇ndex.js文件中,修改一下jsx的寫(xiě)法。修改成函數(shù)組件:

import jsx from '../src/react/jsx.js'
import ReactDOM from '../src/react-dom/index'

const root = document.querySelector('#root');

function App() {
  return jsx("div", {
    ref: "123",
    children: jsx("span", {
      children: "456"
    })
  });
}

ReactDOM.createRoot(root).render(<App />)

這里因?yàn)樾枰褂梦覀冏约旱膉sx方法。所以在App里面返回的依舊是通過(guò)之前的方式進(jìn)行調(diào)用。

1.修改reconcileChildren方法

我們來(lái)回憶一下,在beginWork階段,我們主要是通過(guò)ReactElement,創(chuàng)建FilberNode。而reconcileChildren,就是創(chuàng)建FilberNode的方法。

在之前我們只處理了HostText類(lèi)型和HostComponent類(lèi)型,所以在這個(gè)方法里面,我們要對(duì)函數(shù)類(lèi)型進(jìn)行兼容,而作為函數(shù)組件的ReactElment,它最顯而易見(jiàn)的特點(diǎn)就是type的值是一個(gè)函數(shù)。

例如上面的App組件,對(duì)應(yīng)的ReactElement的type就是App。所以我們可以通過(guò)type來(lái)判斷組件的類(lèi)型:

function reconcileChildren(element) {
  let tag;
  if(typeof element.type === 'function') {
    tag = FunctionComponent
  }
  //其他代碼
  console.log(filberNode)
  return filberNode
}

我們打印一下看看,這個(gè)函數(shù)組件是否滿(mǎn)足預(yù)期:

React源碼解析18(5)------ 實(shí)現(xiàn)函數(shù)組件【修改beginWork和completeWork】,react.js,javascript,ecmascript

2.updateFunctionComponent方法

現(xiàn)在有了tag為FunctionComponent類(lèi)型的FilberNode,在beginWork里面,我們就要對(duì)這個(gè)類(lèi)型的FilberNode進(jìn)行處理:

function beginWork(nowFilberNode) {
  switch (nowFilberNode.tag) {
  	//其他代碼
    case FunctionComponent: {
      return updateFunctionComponent(nowFilberNode)
    }
    //其他代碼
  }
}

現(xiàn)在我們來(lái)實(shí)現(xiàn)updateFunctionComponent方法。
之前對(duì)于HostComponent類(lèi)型的FilberNode,它的子節(jié)點(diǎn)其實(shí)就是它對(duì)應(yīng)的ReactElement。

但是對(duì)于函數(shù)類(lèi)型的FilberNode,我們想一下不就是它自己的返回值嘛?所以我們直接調(diào)用這個(gè)函數(shù)就能拿到它的子FilberNode了。

function updateFunctionComponent(filberNode) {
  const nextChildren = filberNode.type();
  const newFilberNode = reconcileChildren(nextChildren);
  filberNode.child = newFilberNode;
  newFilberNode.return = filberNode;
  beginWork(newFilberNode)
}

2.修改completeWork方法

對(duì)于completeWork方法, 它的主要作用(目前)是給對(duì)應(yīng)的FilberNode增加stateNode,而函數(shù)組件并沒(méi)有自己對(duì)應(yīng)的StateNode,所以直接繼續(xù)遞歸就可以了:

export const completeWork = (filberNode) => {
  const tag = filberNode.tag
  switch (tag) {
	//其他代碼。。。
    case FunctionComponent: {
      completeWork(filberNode.child)
    }
  }
}

3.修改commitWork方法

對(duì)于之前的commitWork,我們是直接將最外層的FilberNode的stateNode掛載了容器上,現(xiàn)在由于最外層的可能是FunctionComponent,它是沒(méi)有自己的stateNode的。所以我們要找到具有stateNode的最外層FilberNode。

import { HostComponent } from "./filberNode";

export function commitWork(filberRootNode) {
  const container = filberRootNode.container;
  let node = filberRootNode.finishedWork;
  while( node.tag !== HostComponent ){
    node = node.child
  }
  container.appendChild(node.stateNode)
}

OK,經(jīng)過(guò)上面的修改,我們的App組件也可以正常渲染了。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-646542.html

到了這里,關(guān)于React源碼解析18(5)------ 實(shí)現(xiàn)函數(shù)組件【修改beginWork和completeWork】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • React源碼解析18(10)------ 實(shí)現(xiàn)多節(jié)點(diǎn)的Diff算法

    在上一篇中,實(shí)現(xiàn)了多節(jié)點(diǎn)的渲染。但是之前寫(xiě)得diff算法,只能適用于單節(jié)點(diǎn)的情況,例如這種情況: 如果對(duì)于多節(jié)點(diǎn)的情況: 之前實(shí)現(xiàn)的diff算法就不會(huì)有效果了,所以在這一篇中,我們主要實(shí)現(xiàn)針對(duì)于多節(jié)點(diǎn)的diff算法。 實(shí)現(xiàn)之前,我們先將index.js修改一下: 在reconcile

    2024年02月12日
    瀏覽(18)
  • React源碼解析18(11)------ 實(shí)現(xiàn)多次setState的批處理

    在React中,如果涉及到了多次setState,組件render幾次。setState是同步的還是異步的。這是一個(gè)很常見(jiàn)的面試題。 而本篇文章,就是主要實(shí)現(xiàn)React中,對(duì)于這部分的性能優(yōu)化,我們稱(chēng)之為批處理。例如當(dāng)我有下面的JSX。 對(duì)于當(dāng)前的點(diǎn)擊事件來(lái)說(shuō),只有最后的setNum(num + 3)是有效的。

    2024年02月11日
    瀏覽(40)
  • React源碼解析18(1)------ React.createElement 和 jsx

    React源碼解析18(1)------ React.createElement 和 jsx

    我們知道在React17版本之前,我們?cè)陧?xiàng)目中是一定需要引入react的。 import React from “react” 即便我們有時(shí)候沒(méi)有使用到React,也需要引入。原因是什么呢? 在React項(xiàng)目中,如果我們使用了模板語(yǔ)法JSX,我們知道它要先經(jīng)過(guò)babel的轉(zhuǎn)譯。那babel會(huì)將JSX轉(zhuǎn)換成什么樣子的格式呢? 可

    2024年02月13日
    瀏覽(21)
  • React源碼解析18(2)------ FilberNode,F(xiàn)ilberRootNode結(jié)構(gòu)關(guān)系

    React源碼解析18(2)------ FilberNode,F(xiàn)ilberRootNode結(jié)構(gòu)關(guān)系

    在上一篇,我們實(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樹(shù)。而這一章節(jié),主要就是簡(jiǎn)單描述一下FilberNode的結(jié)構(gòu)。 首

    2024年02月13日
    瀏覽(20)
  • React源碼解析18(4)------ completeWork的工作流程【mount】

    React源碼解析18(4)------ completeWork的工作流程【mount】

    經(jīng)過(guò)上一章,我們得到的FilberNode已經(jīng)具有了child和return屬性。一顆Filber樹(shù)的結(jié)構(gòu)已經(jīng)展現(xiàn)出來(lái)了。 那我們最終是想在頁(yè)面渲染真實(shí)的DOM。所以我們現(xiàn)在要在completeWork里,構(gòu)建出一顆離屏的DOM樹(shù)。 之前在說(shuō)FilberNode的屬性時(shí),我們提到過(guò)一個(gè)屬性stateNode。它就是用來(lái)保存每個(gè)

    2024年02月13日
    瀏覽(27)
  • Mobx在非react組件中修改數(shù)據(jù),在ts/js中修改數(shù)據(jù)實(shí)現(xiàn)響應(yīng)式更新

    Mobx在非react組件中修改數(shù)據(jù),在ts/js中修改數(shù)據(jù)實(shí)現(xiàn)響應(yīng)式更新

    我們都之前在封裝mobx作為數(shù)據(jù)存儲(chǔ)的時(shí)候,使用到了useContext作為包裹,將store變成了一個(gè)hooks使用,封裝代碼: 但是我們都知道hooks只能在函數(shù)組件中或者h(yuǎn)ooks中使用,不能在ts/js代碼中使用,但是我這里有一個(gè)需求,想每次發(fā)送接口請(qǐng)求的時(shí)候,做一個(gè)后置處理器,用于獲取

    2024年02月11日
    瀏覽(20)
  • React 18 在組件間共享狀態(tài)

    React 18 在組件間共享狀態(tài)

    參考文章 有時(shí)候,希望兩個(gè)組件的狀態(tài)始終同步更改。要實(shí)現(xiàn)這一點(diǎn),可以將相關(guān) state 從這兩個(gè)組件上移除,并把 state 放到它們的公共父級(jí),再通過(guò) props 將 state 傳遞給這兩個(gè)組件。這被稱(chēng)為“狀態(tài)提升”,這是編寫(xiě) React 代碼時(shí)常做的事。 在這個(gè)例子中,父組件 Accordion 渲

    2024年02月10日
    瀏覽(25)
  • React 18 state 狀態(tài)更新函數(shù)

    參考文章 設(shè)置組件 state 會(huì)把一次重新渲染加入隊(duì)列。但有時(shí)可能會(huì)希望在下次渲染加入隊(duì)列之前對(duì) state 的值執(zhí)行多次操作。為此,了解 React 如何批量更新 state 會(huì)很有幫助。 在下面的示例中,可能會(huì)認(rèn)為點(diǎn)擊 “+3” 按鈕會(huì)使計(jì)數(shù)器遞增三次,因?yàn)樗{(diào)用了 setNumber(number +

    2024年02月13日
    瀏覽(25)
  • 【React】React18+Typescript+craco配置最小化批量引入Svg并應(yīng)用的組件

    【React】React18+Typescript+craco配置最小化批量引入Svg并應(yīng)用的組件

    無(wú)論是哪種 Web UI 框架都不可避免的要與 Svg 打交道,那么批量引入才更方便管理 Svg 。 https://ryanhutzley.medium.com/dynamic-svg-imports-in-create-react-app-d6d411f6d6c6 https://github.com/airbnb/babel-plugin-inline-react-svg/issues/51 https://blog.shianqi.com/2017/12/13/Webpack/SVG-sprite/ https://pganalyze.com/blog/building-svg

    2024年04月10日
    瀏覽(29)
  • react18 hooks自定義移動(dòng)端Popup彈窗組件RcPop

    react18 hooks自定義移動(dòng)端Popup彈窗組件RcPop

    基于 React18 Hooks 實(shí)現(xiàn)手機(jī)端彈框組件 RcPop react-popup 基于 react18+hook 自定義多功能彈框組件。整合了 msg/alert/dialog/toast及android/ios 彈窗效果。支持 20+ 自定義參數(shù)、 組件式+函數(shù)式 調(diào)用方式,全方位滿(mǎn)足各種彈窗場(chǎng)景需求。 在需要使用彈窗的頁(yè)面引入組件。 RcPop支持? 組件式+函

    2024年02月15日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包