自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

自己造一個ReactDOM

開發(fā) 前端
本文會教你如何基于官方的reconciler,實現(xiàn)迷你ReactDOM。如果你想在任何可以繪制UI的環(huán)境使用React,都可以利用react-reconciler實現(xiàn)該環(huán)境下的React。

[[436840]]

大家好,我卡頌。

React可以看作是三部分的組合:

  • scheduler,調(diào)度器,用于調(diào)度任務(wù)
  • reconciler,協(xié)調(diào)器,用于計算任務(wù)造成的副作用
  • renderer,渲染器,用于在宿主環(huán)境執(zhí)行副作用

這三者都是獨(dú)立的包,我們項目里引入的ReactDOM可以看作是以下三部分代碼打包而成:

  • scheduler的主要邏輯
  • reconciler部分邏輯
  • ReactDOM renderer的主要邏輯

本文會教你如何基于官方的reconciler,實現(xiàn)迷你ReactDOM。

本文參考Hello World Custom React Renderer[1]

項目初始化

通過CRA建立項目(或用已有項目):

  1. create-react-app xxx 

新建customRenderer.js,引入react-reconciler并完成初始化:

  1. // 本文使用的reconciler版本是0.26.2 
  2. import ReactReconciler from 'react-reconciler'
  3.  
  4. const hostConfig = {}; 
  5. const ReactReconcilerInst = ReactReconciler(hostConfig); 

其中hostConfig就是宿主環(huán)境的配置項。

最后,customRenderer.js導(dǎo)出一個包含render方法的對象:

  1. export default { 
  2.   render: (reactElement, domElement, callback) => { 
  3.     // 創(chuàng)建根節(jié)點(diǎn) 
  4.     if (!domElement._rootContainer) { 
  5.       domElement._rootContainer = ReactReconcilerInst.createContainer(domElement, false); 
  6.     } 
  7.  
  8.     return ReactReconcilerInst.updateContainer(reactElement, domElement._rootContainer, null, callback); 
  9.   } 
  10. }; 

在項目入口文件,將ReactDOM換成我們實現(xiàn)的CustomRenderer:

  1. import ReactDOM from 'react-dom'
  2. import CustomRenderer from './customRenderer'
  3.  
  4. // 替換ReactDOM 
  5. CustomRenderer.render( 
  6.   <App />, 
  7.   document.getElementById('root'
  8. ); 

實現(xiàn)ReactDOM接下來我們實現(xiàn)hostConfig配置,首先填充空函數(shù)避免應(yīng)用報錯:

  1. const hostConfig = { 
  2.   supportsMutation: true
  3.   getRootHostContext() {}, 
  4.   getChildHostContext() {}, 
  5.   prepareForCommit() {}, 
  6.   resetAfterCommit() {}, 
  7.   shouldSetTextContent() {}, 
  8.   createInstance() {}, 
  9.   createTextInstance() {}, 
  10.   appendInitialChild() {}, 
  11.   finalizeInitialChildren() {}, 
  12.   clearContainer() {}, 
  13.   appendInitialChild() {}, 
  14.   appendChild() {}, 
  15.   appendChildToContainer() {}, 
  16.   prepareUpdate() {}, 
  17.   commitUpdate() {}, 
  18.   commitTextUpdate() {}, 
  19.   removeChild() {} 

注意這里唯一一個Boolean類型的配置項supportsMutation,他表示宿主環(huán)境的API支持mutation。

這是DOM API的工作方式,比如element.appendChild、element.removeChild。如果是Native環(huán)境則不是這種工作方式。

接下來我們來實現(xiàn)這些API。

實現(xiàn)API

這些API可以分為如下幾類。

初始化環(huán)境信息

getRootHostContext與getChildHostContext用于初始化上下文信息。

生成DOM節(jié)點(diǎn)

  • createInstance用于創(chuàng)建DOM節(jié)點(diǎn)
  • createTextInstance用于創(chuàng)建文本節(jié)點(diǎn)

可以將createTextInstance實現(xiàn)如下:

  1. createTextInstance: (text) => { 
  2.   return document.createTextNode(text); 

關(guān)鍵邏輯的判斷

shouldSetTextContent用于判斷組件的children是否是文本節(jié)點(diǎn),實現(xiàn)如下:

  1. shouldSetTextContent: (_, props) => { 
  2.     return typeof props.children === 'string' || typeof props.children === 'number'
  3. }, 

DOM操作

appendInitialChild用于插入DOM節(jié)點(diǎn),實現(xiàn)如下:

  1. appendInitialChild: (parent, child) => { 
  2.   parent.appendChild(child); 
  3. }, 

commitTextUpdate用于改變文本節(jié)點(diǎn),實現(xiàn)如下:

  1. commitTextUpdate(textInstance, oldText, newText) { 
  2.   textInstance.text = newText; 
  3. }, 

removeChild用于刪除子節(jié)點(diǎn),實現(xiàn)如下:

  1. removeChild(parentInstance, child) { 
  2.   parentInstance.removeChild(child); 

當(dāng)實現(xiàn)了所有API后,頁面就能正常渲染了:

完整實現(xiàn)的Demo地址見:完整Demo地址[2]

總結(jié)

經(jīng)過本文的學(xué)習(xí),我們實現(xiàn)了一個簡易ReactDOM。

如果你想在任何可以繪制UI的環(huán)境使用React,都可以利用react-reconciler實現(xiàn)該環(huán)境下的React。

比如,Introduction To React Native Renderers[3]教你如何在Native環(huán)境實現(xiàn)React。

參考資料

[1]Hello World Custom React Renderer:

https://agent-hunt.medium.com/hello-world-custom-react-renderer-9a95b7cd04bc

[2]完整Demo地址:

https://codesandbox.io/s/quiet-feather-05gvk?file=/src/index.js

[3]Introduction To React Native Renderers:

https://agent-hunt.medium.com/introduction-to-react-native-renderers-aka-react-native-is-the-java-and-react-native-renderers-are-828a0022f433

 

責(zé)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2024-12-06 09:58:09

2022-11-29 12:53:36

機(jī)器人物理MIT

2011-02-28 09:22:47

SQLite記賬簿

2019-12-26 14:30:54

LinuxPython硬件

2017-03-02 13:31:02

監(jiān)控系統(tǒng)

2022-04-08 08:48:16

線上事故日志訂閱者

2022-08-09 10:00:57

ViteTypeScripVue3

2024-01-08 13:47:00

代碼分析工具

2012-07-19 13:49:20

2021-06-26 16:24:21

Linux命令系統(tǒng)

2015-07-03 11:27:30

程序員自己神器

2021-04-25 08:58:00

Go拍照云盤

2017-02-14 10:20:43

Java Class解析器

2023-08-31 22:05:02

SAN環(huán)境存儲

2020-06-18 10:36:12

GitHub代碼開發(fā)者

2022-06-10 14:52:46

開源項目字節(jié)跳動

2019-09-02 13:57:07

Helm Chart工具Kubernetes

2020-08-24 07:33:20

CSS框架 SASS

2021-08-04 11:55:45

Python天氣查詢PySide2

2015-06-02 09:51:40

iOS網(wǎng)絡(luò)請求封裝接口
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號