• react-渲染过程--新节点挂载



    渲染: 生成用于显示的对象, 以及将这些对象转化为真实的dom对象

    名词解释(本文章,不是针对react)

    • React元素: 通过React.createElement创建(语法糖jsx)
    • React节点: 专门用于渲染到ui界面的对象
    • 节点类型:
      • DOM节点: 创建该节点的React元素类型是一个字符串(div, p, h1等)
      • 组件节点: 创建该节点的React元素类型是一个函数或者是一个类
      • 文本节点: 由字符串创建
      • 空节点: null, undefined, boolean
      • 数组节点: 该节点由一个数组创建
    • 真实DOM: 通过document.createElement创建
    • 递归: 返回渲染第1步(根1)进行新的渲染操作

    首次渲染(新节点渲染)

    1. 通过参数的值创建节点(例: React.createElement(‘div’, {props}, child1, child2))
    2. 根据不同的节点,做不同的事情
      1. 文本节点: 通过document.createTextNode创建真实的文本节点
      2. 空节点: 什么也不做
      3. 数组节点: 遍历数组, 将数组每一项递归创建节点
      4. DOM节点: 通过document.createElement创建真实的DOM对象,然后立即设置该真实DOM的各种属性,然后遍历对应React元素的Children属性,进行递归
      5. 组件节点
        1. 函数组件: 调用函数(函数需返回一个可以生成节点的内容),将函数的返回结果递归生成节点
        2. 类组件
          1. 创建该类的实例
          2. 立即调用对象的生命周期方法: static getDerivedStateFromProps
          3. 运行该对象的render方法,得到节点对象,递归渲染
          4. 将该组件的componentDidMount方法加入到执行队列(先进先出),当整个虚拟DOM树构建完毕,并将真实DOM挂载到容器中后,执行该队列
    3. 生成的虚拟DOM将会被保存,以便后续使用
    4. 将之前生成的真实DOM对象挂载到容器中

    例子

    代码

    APP.js

    import React, { Component } from 'react'
    
    function CompB() {
      return (
        <div>
          <h1>标题</h1>
          {['abc', null]}
        </div>
      )
    }
    
    
    class CompA extends Component {
      state = {}
    
      constructor() {
        super()
        console.log('4', 'CompA constructor')
      }
    
      static getDerivedStateFromProps(props, state) {
        console.log('5', 'CompA getDerivedStateFromProps')
        return null
      }
    
      componentDidMount() { 
        console.log('7', 'CompA componentDidMount')
      }
    
      
      componentWillUnmount() {
        console.log('9', "CompA componentWillUnmount")
      }
    
      render() {
        console.log('6', 'CompA render')
        return (
          <div>
            <CompB />
          </div>
        )
      }
    }
    
    
    export default class App extends Component {
    
      state = {}
    
      constructor() {
        super()
        console.log('1', 'App constructor')
      }
    
      static getDerivedStateFromProps(props, state) {
        console.log('2', 'App getDerivedStateFromProps')
        return null
      }
    
      componentDidMount() { 
        console.log('8', 'App componentDidMount')
      }
    
      componentWillUnmount() {
        console.log('10', "App componentWillUnmount")
      }
    
      render() {
        console.log('3', 'App render')
        return (
          <div>
            <CompA />
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    打印

    由于react现在严格模式(React.StrictMode)下组件会运行两次 所以运行结果为 112233445566789(10)78
    去掉
    严格模式
    运行一次就是 12345678 我给排好续了,按照渲染流程应该不难理解

    图示虚拟DOM树

    虚拟DOM树

  • 相关阅读:
    Kotlin协程:线程的桥接与切换
    一个项目进行测试的一些最基本环境
    开放领域问答机器人2——开发流程和方案
    TCP的发送系列 — 发送缓存的管理(一)
    786. 第k个数
    Vue表单修饰符:v-model.lazy、v-model.number、v-model.trim
    通过Docker安装ElasticSearch和Kibana
    Linux内核设计与实现 第八章 下半部和推后执行的工作
    MySql用户管理与引擎介绍
    docker 部署 clickhouse
  • 原文地址:https://blog.csdn.net/yuey0809/article/details/126154788