学习笔记:React中JSX转换成真实DOM的过程

176 阅读1分钟

参考:# React源码分析1-jsx转换及React.createElement

参考:# 来看看React Jsx转换成真实DOM过程,让你更好理解Jsx的转化

是什么?

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Hello from '../components/Hello'

export default class App extends Component { 
    render() { 
        return (
            <div>
                <img src="avatar.png" className="profile" />
                <Hello />
            </div>
        )
        
    } 
}
ReactDOM.render(<App />, document.getElementById('root'))

以上代码中编写了JSX语句 return ( <div> <img src="avatar.png" className="profile" /> <Hello /> </div> ),那么该语句是如何被浏览器识别并执行的呢?

image.png

16.x版本及以前

  1. @babel/preset-react将JSX语句转换为React.createElement(...)的js代码,举例如下:

    • 在转化过程中,babel在编译时会判断 JSX 中组件的首字母:

      • 当首字母为小写时,其被认定为原生 DOM 标签,createElement 的第一个变量被编译为字符串
      • 当首字母为大写时,其被认定为自定义组件,createElement 的第一个变量被编译为对象
// JSX模板内容
<div>
    <img src="avatar.png" className="profile" />
    <Hello />
</div>

// babel转换后的js代码
React.createElement(
    "div",
    null,
    React.createElement("img", {
        src: "avatar.png",
        className: "profile"
    }),
    React.createElement(Hello, null)
);

  1. React.createElement经过一系列操作,最终构造成一个虚拟DOM对象——ReactElement对象
  2. ReactDOM.render将得到的虚拟DOM挂载到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM

PS:APIReact.createElement的源码内容可在文章开头的参考中学习

17.x版本及以后

  1. react/jsx-runtime将JSX语句转换为一个虚拟DOM对象——ReactElement对象
  2. ReactDOM.render将得到的虚拟DOM挂载到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM