目录
- 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 是它的语法糖。
<div></div><App />
2,它有一个 type 属性,用于标记类型。
常见类型举例:
const ele = <div></div>;
console.log(ele);
普通 DOM

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

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

1.2,React 节点
专门用于渲染到页面的特定对象,
- 通过React 元素创建;
- ReactDOM 通过它来进行渲染。
1.3,节点类型
下面这些都是 React 自己创建的节点类型:
- DOM 节点,创建该节点的 React 元素类型 是一个字符串。
- 组件(Composite)节点,创建该节点的 React 元素类型是一个函数或类。
- 文本(Text)节点,由字符串,数字创建。
- 空(Empty)节点,由
null,undefined,false,true创建。 - 数组节点,由一个数组创建。
举例:
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,不同节点,有不同处理
- 文本节点:通过
document.createTextNode()创建真实的文本节点。 - 空节点:无事发生(但节点存在)。
- DOM节点:通过
document.createElement()创建真实DOM对象,接着立即设置该真实DOM元素的各种属性(属性在props中),然后遍历对应 React 元素的children属性,进行递归操作(回到第1步)。 - 数组节点:遍历数组,对数组的元素创建节点,并进行递归操作(回到第1步)。
- 组件节点:
- 函数组件:调用该函数(函数必须返回可以生成节点的内容),将函数返回的结果进行递归操作(回到第1步)
- 类组件:
- 创建类的实例;
- 调用类的生命周期方法
static getDerivedStateFromProps(); - 调用组件的
render方法,得到节点对象进行递归操作(回到第1步); - 将组件的生命周期方法
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树:
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树:
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树:
以上。