react学习—渲染过程(首次渲染)

一、渲染过程

1、渲染原理

渲染:生成用于显示的对象,以及将这些对象形成真实的DOM对象

  • React元素:React Element,通过React.createElement创建(语法糖:JSX)

    • 例如:
    • <div><h1>标题</h1></div>
    • <App />
  • React节点:专门用于渲染到UI界面的对象,React会通过React元素,创建React节点,ReactDOM一定是通过React节点来进行渲染的
    在这里插入图片描述

  • 节点类型:

    • React DOM节点:创建该节点的React元素类型是一个字符串
import React from 'react';
import ReactDOM from 'react-dom';
const app = <div><h1>标题</h1></div>
ReactDOM.render(app, document.getElementById('root'));

在这里插入图片描述

  • React 组件节点:创建该节点的React元素类型是一个函数或是一个类
import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App"
ReactDOM.render(<App />, document.getElementById('root'));

在这里插入图片描述

  • React 文本节点:由字符串、数字创建的
import React from 'react';
import ReactDOM from 'react-dom';
const app = 'Hello World'
ReactDOM.render(app, document.getElementById('root'));

在这里插入图片描述

  • React 空节点:由null、undefined、false、true
import React from 'react';
import ReactDOM from 'react-dom';
const app = null
ReactDOM.render(app, document.getElementById('root'));
  • React 数组节点:该节点由一个数组创建
import React from 'react';
import ReactDOM from 'react-dom';
const app = [1,2,3,4]
ReactDOM.render(app, document.getElementById('root'));
  • 真实DOM:通过document.createElement创建的dom元素

2、首次渲染(新节点渲染)

这里总结的是第一次渲染时:

  1. 通过参数的值创建节点
  2. 根据不同的节点,做不同的事情
    1. 文本节点:通过document.createTextNode创建真实的文本节点
    2. 空节点:什么都不做
    3. 数组节点:遍历数组,将数组每一项递归创建节点(回到第1步进行反复操作,直到遍历结束)
    4. DOM节点:通过document.createElement创建真实的DOM对象,然后立即设置该真实DOM元素的各种属性,然后遍历对应React元素的children属性,递归操作(回到第1步进行反复操作,直到遍历结束)
    5. 组件节点
      1. 函数组件:调用函数(该函数必须返回一个可以生成节点的内容),将该函数的返回结果递归生成节点(回到第1步进行反复操作,直到遍历结束)
      2. 类组件:
        1. 创建该类的实例
        2. 立即调用对象的生命周期方法:static getDerivedStateFromProps
        3. 运行该对象的render方法,拿到节点对象(将该节点递归操作,回到第1步进行反复操作)
        4. 将该组件的componentDidMount加入到执行队列(先进先出,先进先执行),当整个虚拟DOM树全部构建完毕,并且将真实的DOM对象加入到容器中后,执行该队列
  3. 生成出虚拟DOM树之后,将该树保存起来,以便后续使用
  4. 将之前生成的真实的DOM对象,加入到容器中。

阅读上面各组件的渲染过程,配合下面的例子进行理解

例:DOM节点

import React from 'react';
import ReactDOM from 'react-dom';
const app = <div className="assaf">
    <h1>
        标题
        {["abc", null, <p>段落</p>]}
    </h1>
    <p>
        {undefined}
    </p>
</div>;
ReactDOM.render(app, document.getElementById('root'));

在这里插入图片描述

首次渲染我们的app节点时,按照上述的流程,最终生成了虚拟dom树并保存起来,将生成的真实的DOM对象加载到页面中。
在这里插入图片描述
例:函数组件节点

App.js
import React from 'react'

function Comp1(props) {
  return <h1>Comp1 {props.n}</h1>
}

export default function App(props) {
  return (
      <div>
          <Comp1 n={5} />
      </div>
  )
}
import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App"

const app = <App />;
ReactDOM.render(app, document.getElementById('root'));

依旧遵循上述过程,先调用组件App,返回DOM节点div…,最终生成虚拟DOM树
在这里插入图片描述
例:类组件节点

import React from 'react'


class Comp1 extends React.Component {
  state = {}
  constructor(props){
    super(props);
    console.log(4,"Comp1 constructor")
  }
  static getDerivedStateFromProps(props,state){
    console.log(5,"Comp1 getDerivedStateFromProps")
    return null
  }
  componentDidMount(){
    console.log('b componentDidMount')
  }
  render() {
    console.log(6,"Comp1 render")
      return (
          <h1>Comp1</h1>
      )
  }
}

export default class App extends React.Component {
  state = {}
  constructor(props){
    super(props);
    console.log(1,"App constructor")
  }
  static getDerivedStateFromProps(props,state){
    console.log(2,"App getDerivedStateFromProps")
    return null
  }
  componentDidMount(){
    console.log('a componentDidMount')
  }
  render() {
    console.log(3,"App render")
      return (
          <div>
              <Comp1 />
          </div>
      )
  }
}

通过运行我们发现了输出的结果,其实类组件的渲染过程和函数组件是类似的。由于是等Comp1组件挂载完成,App组件才算挂载完成,所以b比a先输出哦。
在这里插入图片描述

在这里插入图片描述

博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值