React初始化渲染过程示例详解

 更新时间:2023年09月05日 16:38:04   作者:zgwww  
这篇文章主要为大家介绍了React初始化渲染过程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

初始化渲染的过程,我们可以直接对应到React程序中ReactDOM.render函数调用后的结果。

1.环境准备

初始化项目:

npx create-react-app simple-react

删除一些代码,最关键的内容就是:

src/index.js
public/index.html
package.json中的dependencies和scripts:

2.JSX介绍

JSX是JavaScript的一种语法扩展。

JSX到普通Javascript的代码的转化是通过babel完成的。

3.React.createElement编写

DISABLE_NEW_JSX_TRANSFORM=true 禁用掉新的jsxdev转换,使用React.createElement

这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,让你能够以unix方式设置环境变量,然后在windows上也能兼容运行。

npm i cross-env -D
package.json
"start": "cross-env DISABLE_NEW_JSX_TRANSFORM=true react-scripts start",

react17之前通过Babel把jsx转换为虚拟DOM

<div> Hello Simple React </div>
React.createElement("div", null, "Hello Simple React")

react.js

import { REACT_ELEMENT } from "./utils"
function createElement(type, properties, children) {
    // debugger
    let ref = properties.ref || null
    let key = properties.key || null
        // 属性可以是可读的、可写的或可删除的。
        // 属性可以是可枚举的(可以通过for…in循环枚举)或不可枚举的。
        // 可以通过Object.defineProperty()等方法定义属性的特性。
        ;['key', 'ref', '__self', '__source'].forEach(key => {
            delete properties[key]
        })
    let props = { ...properties }
    //传参大于3
    if (arguments.length > 3) {
        console.log(arguments)
        props.children = Array.prototype.slice.call(arguments, 2)
    } else {
        props.children = children
    }
    return {
        //$$--唯一性,jsx转换成为的类型
        $$typeof: REACT_ELEMENT,
        type,
        ref,//操作DOM
        key,//diff比较
        props
    }
}
const React = {
    createElement
}
export default React

4.ReactDOM.render函数编写

初始化渲染第一步:实现函数React.createElement

初始化渲染第二步:实现函数ReactDOM.render

react-dom.js

import { REACT_ELEMENT } from './utils'
//初始化渲染(不止挂载操作)
function render(VNode, containerDOM) {
    // 将虚拟DOM转化成真实DOM
    // 将得到的真实DOM挂载到contanerDOM中
    mount(VNode, containerDOM)
}
function mount(VNode, containerDOM) {
    let newDOM = createDOM(VNode)
    newDOM && containerDOM.appendChild(newDOM)
}
function createDOM(VNode) {
    // 1.根据类型创建元素 2.处理子元素,VNode是树形结构 3.处理属性值
    const { type, props } = VNode
    let dom;
    //typeof === REACT_ELEMENT代表虚拟DOM VNode
    if (type && VNode.$$typeof === REACT_ELEMENT) {
        dom = document.createElement(type)
    }
    if (props) {
        //子节点存在
        if (typeof props.children === 'object' && props.children.type) {
            //递归,创建子节点
            mount(props.children, dom)
        } else if (Array.isArray(props.children)) {
            //多个子节点
            mountArray(props.children, dom)
        } else if (typeof props.children === 'string') {
            //文本节点
            dom.appendChild(document.createTextNode(props.children))
        }
    }
    // TODO:处理属性值
    //setPropsForDOM(dom, props)
    return dom
}
//多个子节点处理
function mountArray(children, parent) {
    console.log('parent', parent, children)
    if (!Array.isArray(children)) return
    for (let i = 0; i < children.length; i++) {
        if (typeof children[i] === 'string') {
            //创建文本节点
            parent.appendChild(document.createTextNode(children[i]))
        } else {
            mount(children[i], parent)
        }
    }
}
const ReactDOM = {
    render
}
export default ReactDOM

5.实现函数setPropsForDOM进行属性更新

// 【这里需要注意jsx属性名称的写法】

ReactDOM.render(<div className='test-class' style={{color: 'red'}}>Simple React App<span>xx1</span><span>xx2</span></div>, document.getElementById('root'))
function setPropsForDOM(dom, VNodeProps = {}) {
    if (!dom) return
    for (let key in VNodeProps) {
        if (key === 'children') continue
        //^开头,on开头,A-Z之间一个,.匹配单个字符,
        //*号匹配一个字母或者数字出现一次或者多次 onclick
        if (/^on[A-Z].*/.test(key)) {
            // TODO: 事件处理
        } else if (key === 'style') {
            Object.keys(VNodeProps[key]).forEach(styleName => {
                dom.style[styleName] = VNodeProps[key][styleName]
            })
        } else {
            dom[key] = VNodeProps[key]
        }
    }
}

总结

从JSX源代码(<div>Hello JSX</div>)到显示到界面上,需要经历哪些关键环节。

JSX -> 转译成函数调用 -> 执行函数调用返回虚拟DOM -> 将虚拟DOM转化成DOM -> 将生成的DOM挂载到DOM上

以上就是React初始化渲染过程示例详解的详细内容,更多关于React初始化渲染的资料请关注脚本之家其它相关文章!

相关文章

  • react-native-video实现视频全屏播放的方法

    react-native-video实现视频全屏播放的方法

    这篇文章主要介绍了react-native-video实现视频全屏播放的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 基于React和antd实现自定义进度条的示例代码

    基于React和antd实现自定义进度条的示例代码

    在现代 Web 开发中,进度条是一种常见且实用的 UI 组件,用于直观地向用户展示任务的完成进度,本文将详细介绍如何使用 React 来构建一个自定义的进度条,它不仅能够动态展示进度,还具备额外的信息提示功能,需要的朋友可以参考下
    2025-03-03
  • react如何获取URL中参数

    react如何获取URL中参数

    这篇文章主要介绍了react如何获取URL中参数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 从零开始搭建一个react项目开发

    从零开始搭建一个react项目开发

    这篇文章主要介绍了从零开始搭建一个react项目开发,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • React-router v4 路由配置方法小结

    React-router v4 路由配置方法小结

    本篇文章主要介绍了React-router v4 路由配置方法小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • React实现路由返回拦截的三种方式

    React实现路由返回拦截的三种方式

    最近项目为了避免用户误操作导致数据丢失,增加返回拦截功能,但是之前由于qiankun的报错导致这个功能一直有一些问题,所以专门独立搞了一个专题研究在react中各种方式实现这个功能,需要的朋友可以参考下
    2024-05-05
  • React生命周期函数图解介绍

    React生命周期函数图解介绍

    生命周期函数指在某一时刻组件会自动调用并执行的函数。React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法
    2022-11-11
  • 使用webpack配置react-hot-loader热加载局部更新

    使用webpack配置react-hot-loader热加载局部更新

    这篇文章主要介绍了使用webpack配置react-hot-loader热加载局部更新,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • react高阶组件经典应用之权限控制详解

    react高阶组件经典应用之权限控制详解

    在React中,高阶组件是重用组件逻辑的一项高级技术。下面这篇文章主要给大家介绍了关于react高阶组件经典应用之权限控制的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • 解决React报错Property 'X' does not exist on type 'HTMLElement'

    解决React报错Property 'X' does not 

    这篇文章主要为大家介绍了解决React报错Property 'X' does not exist on type 'HTMLElement',有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论