React@16.x(20)渲染流程-首次渲染

作者 : admin 本文共2478个字,预计阅读时间需要7分钟 发布时间: 2024-06-5 共4人阅读

目录

  • 1,渲染的前置知识点
    • 1.1,React 元素
    • 1.2,React 节点
    • 1.3,节点类型
    • 1.4,真实DOM
  • 2,首次渲染
    • 2.1,根据参数创建节点
    • 2.2,不同节点,有不同处理
    • 2.3,生成虚拟DOM树
    • 2.4,将生成的真实DOM对象,加入到容器中
  • 3,部分举例说明
    • 3.1
    • 3.2
    • 3.3

1,渲染的前置知识点

渲染:将 React 元素生成特定对象,并通过这些对象生成真实 DOM 对象,加入到容器中。

1.1,React 元素

1,通过 React.createElement() 创建,JSX 是它的语法糖。

2,它有一个 type 属性,用于标记类型

常见类型举例:

const ele = <div></div>;
console.log(ele);

普通 DOM

React@16.x(20)渲染流程-首次渲染插图

class Child extends Component {}
console.log(<Child />);

React@16.x(20)渲染流程-首次渲染插图(1)

函数

function Child() {}
console.log(<Child />);

React@16.x(20)渲染流程-首次渲染插图(2)

1.2,React 节点

专门用于渲染到页面的特定对象

  • 通过React 元素创建;
  • ReactDOM 通过它来进行渲染

1.3,节点类型

下面这些都是 React 自己创建的节点类型:

  1. DOM 节点,创建该节点的 React 元素类型 是一个字符串。
  2. 组件(Composite)节点,创建该节点的 React 元素类型是一个函数或类。
  3. 文本(Text)节点,由字符串,数字创建。
  4. 空(Empty)节点,由 nullundefinedfalsetrue 创建。
  5. 数组节点,由一个数组创建。

举例:

1和2已经有例子了,不多赘述。

3,4,5说的【创建】是指通过 React 元素创建,也就是说字符串,数字,null 等也都会被创建为 React 元素,再创建 React 节点。

const ele = "text"; // 或 123, null, true 等 
console.log(<ele />);

// 数组可以直接渲染
export default class App extends Component {
    render() {
        return (
            <>
                123
                {true}
                {ele}
                [1,2,3]
            </>
        );
    }
}

注意,节点类型中并不包括普通对象,所以普通对象无法渲染

1.4,真实DOM

通过 document.createElement() 创建的 DOM 元素。

2,首次渲染

ReactDOM.render(参数1, 参数2) 的过程中,React 内部会将React 元素(参数1)先转为 React 节点,再进行渲染(挂载到参数2)。

2.1,根据参数创建节点

参数指 ReactDOM.render() 的第一个参数:

ReactDOM.render(app, document.getElementById('root'));

2.2,不同节点,有不同处理

  1. 文本节点:通过 document.createTextNode() 创建真实的文本节点。
  2. 空节点:无事发生(但节点存在)。
  3. DOM节点:通过 document.createElement() 创建真实DOM对象,接着立即设置该真实DOM元素的各种属性(属性在 props 中),然后遍历对应 React 元素的 children 属性,进行递归操作(回到第1步)。
  4. 数组节点:遍历数组,对数组的元素创建节点,并进行递归操作(回到第1步)。
  5. 组件节点:
    1. 函数组件:调用该函数(函数必须返回可以生成节点的内容),将函数返回的结果进行递归操作(回到第1步)
    2. 类组件:
      1. 创建类的实例;
      2. 调用类的生命周期方法 static getDerivedStateFromProps()
      3. 调用组件的 render 方法,得到节点对象进行递归操作(回到第1步);
      4. 将组件的生命周期方法 componentDidMount() 加入到执行队列(先进先出)。当整个虚拟DOM树构建完成,并将真实DOM对象加入到容器之后,执行该队列。

结合类组件的第3步和第4步。可以得到父子组件生命周期的执行顺序:
getDerivedStateFromProps –> 父 render –>
getDerivedStateFromProps –> 子 render ->
componentDidMount() –> 父 componentDidMount()

2.3,生成虚拟DOM树

对节点处理后,会生成整个虚拟DOM树,同时节点对应的真实DOM也生成了。

React 会将虚拟DOM树保存起来,后续更新时会进行对比。

2.4,将生成的真实DOM对象,加入到容器中

ReactDOM.render() 的第2个参数就是容器,通过 appendChild() 方法将生成的真实DOM对象,加入容器中。

ReactDOM.render(app, document.getElementById('root'));

3,部分举例说明

3.1

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

得到的虚拟DOM树:

React@16.x(20)渲染流程-首次渲染插图(3)

3.2

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

function App(props) {
    return (
        <div>
            <Comp1 n={5} />
        </div>
    )
}

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

得到的虚拟DOM树:

React@16.x(20)渲染流程-首次渲染插图(4)

3.3

class Comp1 extends React.Component {
    render() {
        return (
            <h1>Comp1</h1>
        )
    }
}

class App extends React.Component {
    render() {
        return (
            <div>
                <Comp1 />
            </div>
        )
    }
}

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

得到的虚拟DOM树:

React@16.x(20)渲染流程-首次渲染插图(5)


以上。

本站无任何商业行为
个人在线分享 » React@16.x(20)渲染流程-首次渲染
E-->