React源碼解析18(5)------ 實現函數組件【修改beginWork和completeWork】

摘要

經過之前的幾篇文章,我們實現了基本的jsx,在頁面渲染的過程。但是如果是通過函數組件寫出來的組件,還是不能渲染到頁面上的。
所以這一篇,主要是對之前寫得方法進行修改,從而能夠顯示函數組件,所以現在我們在index.js文件中,修改一下jsx的寫法。修改成函數組件:

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 />)

這里因為需要使用我們自己的jsx方法。所以在App里面返回的依舊是通過之前的方式進行調用。

1.修改reconcileChildren方法

我們來回憶一下,在beginWork階段,我們主要是通過ReactElement,創建FilberNode。而reconcileChildren,就是創建FilberNode的方法。

在之前我們只處理了HostText類型和HostComponent類型,所以在這個方法里面,我們要對函數類型進行兼容,而作為函數組件的ReactElment,它最顯而易見的特點就是type的值是一個函數。

例如上面的App組件,對應的ReactElement的type就是App。所以我們可以通過type來判斷組件的類型:

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

我們打印一下看看,這個函數組件是否滿足預期:

在這里插入圖片描述

2.updateFunctionComponent方法

現在有了tag為FunctionComponent類型的FilberNode,在beginWork里面,我們就要對這個類型的FilberNode進行處理:

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

現在我們來實現updateFunctionComponent方法。
之前對于HostComponent類型的FilberNode,它的子節點其實就是它對應的ReactElement。

但是對于函數類型的FilberNode,我們想一下不就是它自己的返回值嘛?所以我們直接調用這個函數就能拿到它的子FilberNode了。

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

2.修改completeWork方法

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

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

3.修改commitWork方法

對于之前的commitWork,我們是直接將最外層的FilberNode的stateNode掛載了容器上,現在由于最外層的可能是FunctionComponent,它是沒有自己的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,經過上面的修改,我們的App組件也可以正常渲染了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36980.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36980.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36980.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【深度學習】NLP中的對抗訓練

在NLP中&#xff0c;對抗訓練往往都是針對嵌入層&#xff08;包括詞嵌入&#xff0c;位置嵌入&#xff0c;segment嵌入等等&#xff09;開展的&#xff0c;思想很簡單&#xff0c;即針對嵌入層添加干擾&#xff0c;從而提高模型的魯棒性和泛化能力&#xff0c;下面結合具體代碼…

Spark 學習記錄

基礎 SparkContext是什么&#xff1f;有什么作用&#xff1f; https://blog.csdn.net/Shockang/article/details/118344357 SparkContext 是什么&#xff1f; SparkContext 是通往 Spark 集群的唯一入口&#xff0c;可以用來在 Spark 集群中創建 RDDs 、累加和廣播變量( Br…

【數據庫基礎】Mysql下載安裝及配置

下載 下載地址&#xff1a;https://downloads.mysql.com/archives/community/ 當前最新版本為 8.0版本&#xff0c;可以在Product Version中選擇指定版本&#xff0c;在Operating System中選擇安裝平臺&#xff0c;如下 安裝 MySQL安裝文件分兩種 .msi和.zip [外鏈圖片轉存失…

C++11時間日期庫chrono的使用

chrono是C11中新加入的時間日期操作庫&#xff0c;可以方便地進行時間日期操作&#xff0c;主要包含了&#xff1a;duration, time_point, clock。 時鐘與時間點 chrono中用time_point模板類表示時間點&#xff0c;其支持基本算術操作&#xff1b;不同時鐘clock分別返回其對應…

vue中router路由的原理?兩種路由模式如何實現?(vue2) -(上)

平時我們編寫路由時&#xff0c;通常直接下載插件使用&#xff0c;在main.js文件中引入直接通過引入vue-router中的Router通過Vue.use使用以后定義一個routeMap數組&#xff0c;里邊是我們編寫路由的地方&#xff0c;最后通過實例化一個 Router實例 將routes我們定義的routeMao…

Docker中部署Nginx

1.Nginx部署需求 2.操作教程 3.實際步驟 把配置粘過來。

客戶端遠程啟動服務器腳本文件

目錄 軟件需求 實現 方法1 方法2 方法3 軟件需求 有兩臺計算機&#xff0c;一臺是linux客戶端&#xff0c;另一臺是linux服務器。要求操作員可以在客戶端遠程啟動服務器上的腳本文件&#xff0c;控制服務器。 實現 方法1 客戶端通過ssh登錄服務器&#xff0c;然后通過…

Cookie、Session、Token的區別

有人或許還停留在它們只是驗證身份信息的機制&#xff0c;但是它們之間的關系你真的弄懂了么&#xff1f; 發展史&#xff1a; Coolie: Netscape Communications 公司引入了 Cookie 概念&#xff0c;作為在客戶端存儲狀態信息的一種方法。初始目的是為了解決 HTTP 的無狀態性…

Python爬蟲:單線程、多線程、多進程

前言 在使用爬蟲爬取數據的時候&#xff0c;當需要爬取的數據量比較大&#xff0c;且急需很快獲取到數據的時候&#xff0c;可以考慮將單線程的爬蟲寫成多線程的爬蟲。下面來學習一些它的基礎知識和代碼編寫方法。 一、進程和線程 進程可以理解為是正在運行的程序的實例。進…

python爬蟲數據解析xpath、jsonpath,bs4

數據的解析 解析數據的方式大概有三種 xpathJsonPathBeautifulSoup xpath 安裝xpath插件 打開谷歌瀏覽器擴展程序&#xff0c;打開開發者模式&#xff0c;拖入插件&#xff0c;重啟瀏覽器&#xff0c;ctrlshiftx&#xff0c;打開插件頁面 安裝lxml庫 安裝在python環境中的Scri…

劍指Offer61.撲克牌中的順子 C++

1、題目描述 從若干副撲克牌中隨機抽 5 張牌&#xff0c;判斷是不是一個順子&#xff0c;即這5張牌是不是連續的。2&#xff5e;10為數字本身&#xff0c;A為1&#xff0c;J為11&#xff0c;Q為12&#xff0c;K為13&#xff0c;而大、小王為 0 &#xff0c;可以看成任意數字。…

并發服務器模型,多線程并發

一、多線程并發完整代碼 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> #include <…

突然讓做性能測試?試試RunnerGo

當前&#xff0c;性能測試已經是一名軟件測試工程師必須要了解&#xff0c;甚至熟練使用的一項技能了&#xff0c;在工作時可能每次發版都要跑一遍性能&#xff0c;跑一遍自動化。性能測試入門容易&#xff0c;深入則需要太多的知識量&#xff0c;今天這篇文章給大家帶來&#…

Rocky Linux更換為國內源

Rocky Linux提供的可供切換的源列表&#xff1a;Mirrors - Mirror Manager 其中以 COUNTRY 列為 CN 的是國內源。 選擇其中一個Rocky Linux 源使用幫助 — USTC Mirror Help 文檔 操作前請做好備份 對于 Rocky Linux 8&#xff0c;使用以下命令替換默認的配置 sed -e s|^mirr…

新能源汽車電控系統

新能源汽車電控系統主要分為&#xff1a;三電系統電控系統、高壓系統電控系統、低壓系統電控系統 三電系統電控系統 包括整車控制器、電池管理系統、驅動電機控制器等。 整車控制器VCU 整車控制器作為電動汽車中央控制單元&#xff0c;是整個控制系統的核心&#xff0c;也是…

zabbix監控mysql數據庫、nginx、Tomcat

zabbix監控mysql數據庫、nginx、Tomcat 一.zabbix監控mysql數據庫 1.環境規劃 hostIP部署zabbix-server192.168.198.17zabbix服務器搭建zabbix-mysql192.168.198.15zabbix客戶端搭建 2.zabbix-server安裝部署&#xff08;192.168.198.17&#xff09; 請參考以下配置&#…

Azure概念介紹

云計算定義 云計算是一種使用網絡進行存儲和處理數據的計算方式。它通過將數據和應用程序存儲在云端服務器上&#xff0c;使用戶能夠通過互聯網訪問和使用這些資源&#xff0c;而無需依賴于本地硬件和軟件。 發展歷史 云計算的概念最早可以追溯到20世紀60年代的時候&#x…

mysql 分庫分表淺析

分表是分散數據庫壓力的好方法。 分表&#xff0c;最直白的意思&#xff0c;就是將一個表結構分為多個表&#xff0c;然后&#xff0c;可以再同一個庫里&#xff0c;也可以放到不同的庫。 當然&#xff0c;首先要知道什么情況下&#xff0c;才需要分表。個人覺得單表記錄條數達…

2023河南萌新聯賽第(五)場:鄭州輕工業大學C-數位dp

鏈接&#xff1a;登錄—專業IT筆試面試備考平臺_牛客網 給定一個正整數 n&#xff0c;你可以對 n 進行任意次&#xff08;包括零次&#xff09;如下操作&#xff1a; 選擇 n 上的某一數位&#xff0c;將其刪去&#xff0c;剩下的左右部分合并。例如 123&#xff0c;你可以選擇…

年至年的選擇仿elementui的樣式

組件&#xff1a;<!--* Author: liuyu liuyuxizhengtech.com* Date: 2023-02-01 16:57:27* LastEditors: wangping wangpingxizhengtech.com* LastEditTime: 2023-06-30 17:25:14* Description: 時間選擇年 - 年 --> <template><div class"yearPicker"…