1. 代码
render() {
return (
<div>
<div className="header">Header</div>
<div className="Conent">
<div>Banner</div>
<ul>
<li>列表数据1</li>
<li>列表数据2</li>
<li>列表数据3</li>
<li>列表数据4</li>
<li>列表数据5</li>
</ul>
</div>
<div className="footer"></div>
</div>
)
}
}
2. 大致过程
在 render 函数中写的 jsx 语法浏览器是不认识的,所以我们只有借助 Babel 工具,将我们写的 JSX 代码转化成浏览器能识别的代码,最终形成代码树,即虚拟DOM,如此才完成渲染。大致渲染过程可参考下面的图片:
3. 转化原理
实际上,JSX 仅仅只是 React.createElement(component,props,...children) 函数的语法糖。所有的 JSX 最终都会被转化为 React.createElement 函数的调用。
-
参数一:type
- 当前 ReactElement 的类型;
- 如果是标签元素,就直接使用字符串表示;
- 如果是组件元素,就直接使用组件元素的名称;
-
参数二:config
- 所有 JSX 中的属性都在 config 中以对象的属性和值的形式存储;
- 比如传入 className 作为元素的 class;
-
参数三:children
- 存放在标签中的内容,以 children 数组的方式进行存储;
- 如果是多个元素,React 内部有对它们进行处理;
4. babel 具体转化后的代码
render() {
const element = React.createElement(
"div",
null,
/*#__PURE__*/ React.createElement(
"div",
{
className: "header"
},
"Header"
),
/*#__PURE__*/ React.createElement(
"div",
{
className: "Conent"
},
/*#__PURE__*/ React.createElement("div", null, "Banner"),
/*#__PURE__*/ React.createElement(
"ul",
null,
/*#__PURE__*/ React.createElement(
"li",
null,
"\u5217\u8868\u6570\u636E1"
),
/*#__PURE__*/ React.createElement(
"li",
null,
"\u5217\u8868\u6570\u636E2"
),
/*#__PURE__*/ React.createElement(
"li",
null,
"\u5217\u8868\u6570\u636E3"
),
/*#__PURE__*/ React.createElement(
"li",
null,
"\u5217\u8868\u6570\u636E4"
),
/*#__PURE__*/ React.createElement("li", null, "\u5217\u8868\u6570\u636E5")
)
),
/*#__PURE__*/ React.createElement("div", {
className: "footer"
})
);
return element
}
...
...
...
const root = ReactDOM.createRoot(document.querySelector('#root'))
root.render(React.createElement(App, null))
5. 虚拟DOM
5.1 渲染虚拟 DOM 原理
本质上是将 JSX 代码转化为 ReactElement 对象,进而被解析成真实 DOM 节点,从而在浏览器上进行渲染。
5.2 声明式编程
虚拟 DOM 帮助我们从命名式编程转成了声明式编程的模式(React 官方说法:Virtual DOM 是一种编程理念)。
- 在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的 JavaScript 对象;
- 可以通过 ReactDOM.render 让虚拟 DOM 和真实 DOM 同步起来,这个过程叫做协调(Reconcilitation)。
5.3 虚拟 DOM的作用
- 在元素发生改变的时候,使用 diff 算法,仅对发生变化的元素进行替换,没发生变化的元素不做改变;
- 跨平台开发。虚拟 DOM 的本质是一个 js 对象,所以可以在不同的端进行渲染,比如在 web端渲染成 div、button;在 iOS/Android 控件渲染成 UIView、UIButton。