JSX => createElement 函数 => ReactElement (对象树) => ReactDOM.render => 真实的DOM
1 JSX基本使用
实际上,JSX 仅仅只是 React.createElement(component,props,…children) 函数的语法糖
所有的 jsx 最终都会被转换成 React.createElement 的函数调用
React.createElement 需要传递的参数
- 参数一:type
- 当前 ReactElement 的类型
- 如果是标签元素,那么就使用字符串 表示 “div”
- 如果是组件元素,那么就直接使用组件的名称
- 参数二:config
- 所有 jsx 中的属性都在 config 中以对象的属性和值的形式存储
- 参数三:chldren
- 存放在 标签中的内容,以 children 数组的方式进行存储
<script type="text/babel">
const message1 = React.createElement("h2", { "class": "a" }, "你好")
ReactDOM.render(message1, document.getElementById('app'))
</script>
注意:如果 是 React.createElement(“div”,null,继续创建元素1,继续创建元素2,继续创建元素3)
在源码中,React.createElement() 函数,只有三个参数
那我们 传递了三个以上的参数,如何匹配?
他会根据 arguments.length - 2 进行 获取
2 虚拟DOM
我们通过 React.createElement 最终创建出来一个 ReactElement 对象
ReactElement 对象 是什么作用? React 为什么要创建它?
原因是 React 利用 ReactElement 对象 组成了一个 js 对象树
js 的对象树 就是大名鼎鼎的虚拟DOM
# 源码中 这样写道
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,// 子元素 可能有一个 或者多个
)
最后, ReactDOM.render 函数,把 对象树,转换成真正的DOM
JSX => createElement 函数 => ReactElement (对象树) => ReactDOM.render => 真实的DOM
class App extends React.Component {
constructor() {
super()
this.state = {
}
}
render() {
// JSX => createElement 函数 => ReactElement (对象树) => ReactDOM.render => 真实的DOM
// var elementObj = React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
// className: "header"
// }, /*#__PURE__*/React.createElement("h1", {
// title: "\u6807\u9898"
// }, "\u6211\u662F\u6807\u9898")), /*#__PURE__*/React.createElement("div", {
// className: "content"
// }, /*#__PURE__*/React.createElement("h2", null, "\u6211\u662F\u9875\u9762\u7684\u5185\u5BB9"), /*#__PURE__*/React.createElement("button", null, "\u6309\u94AE"), /*#__PURE__*/React.createElement("button", null, "+1"), /*#__PURE__*/React.createElement("a", {
// href: "http://www.baidu.com"
// }, "\u767E\u5EA6\u4E00\u4E0B")), /*#__PURE__*/React.createElement("div", {
// className: "footer"
// }, /*#__PURE__*/React.createElement("p", null, "\u6211\u662F\u5C3E\u90E8\u5185\u5BB9")));
// 这两种定义 其实结果都是一样的
var elementObj = (
<div>
<div className="header">
<h1 title="标题">我是标题</h1>
</div>
<div className="content">
<h2>我是页面的内容</h2>
<button>按钮</button>
<button>+1</button>
<a href="http://www.baidu.com">百度一下</a>
</div>
<div className="footer">
<p>我是尾部内容</p>
</div>
</div>)
console.log(elementObj);
return elementObj
}
}
ReactDOM.render(<App />, document.getElementById('app'))
3 为什么采用 虚拟DOM
- 很难跟踪状态发生的改变:原有的开发模式,我们很难跟踪到状态发生的改变,不方便针对我们应用程序进行调试
- 操作真实DOM性能较低:传统的开发模式会进行频繁的DOM操作,而这一的做法性能非常的低
- document.createElement 本身创建出来的就是一个非常复杂的对象
- DOM操作会引起浏览器的回流的重绘