文章目录
JSX的本质
**实际上,jsx仅仅只是
React.createElement(component, props, ...children)
这个函数的语法糖**。
所有的jsx最终都会被转换成React.createElement的函数调用。
createElement需要传递三个参数:
参数一:type
当前元素的类型;
如果是标签元素,那么就使用字符串表示, 例如 “div”;
如果是组件元素,那么就直接使用组件的名称;
参数二:config
所有jsx中的属性都在config中以对象的属性和值的形式存储;
比如传入className作为元素的class;
参数三:children
存放在标签中的内容,以children数组的方式进行存储;
当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方
我们知道默认jsx是通过babel帮我们进行语法转换的,所以我们之前写的jsx代码都需要依赖babel; 我们可以在babel的官网中快速查看转换的过程: 链接: https://babeljs.io/repl/#?presets=react
例如有下面这样一段jsx代码
classAppextendsReact.Component{constructor(){super()}render(){return(<div><div className="header">Header</div><div className="content"><div>Banner</div><ul><li>轮播图1</li><li>轮播图2</li><li>轮播图3</li><li>轮播图4</li><li>轮播图5</li></ul></div><div className="footer">Footer</div></div>)}}const app = ReactDOM.createRoot(document.querySelector("#app"))
app.render(<App/>)
那么也就是说我们可以自己来编写React.createElement代码:
我们没有通过jsx来书写了,界面依然是可以正常的渲染。
另外,在我们编写原生的React情况下,我们就不需要babel相关的内容了(当然真实开发中我们是不会编写原生的React的)
- 所以,type="text/babel"可以被我们删除掉了;
- 所以,
<script src="../react/babel.min.js"></script>
也可以被我们删除掉了;
<divid="app"></div><scriptsrc="../lib/../lib/react.js"></script><scriptsrc="../lib/react-dom.js"></script><script>classAppextendsReact.Component{constructor(){super()}render(){const element = React.createElement("div",null,/*#__PURE__*/React.createElement("div",{className:"header"},"Header"),/*#__PURE__*/React.createElement("div",{className:"content"},/*#__PURE__*/React.createElement("div",null,"Banner"),/*#__PURE__*/React.createElement("ul",null,/*#__PURE__*/React.createElement("li",null,"\u8F6E\u64AD\u56FE1"),/*#__PURE__*/React.createElement("li",null,"\u8F6E\u64AD\u56FE2"),/*#__PURE__*/React.createElement("li",null,"\u8F6E\u64AD\u56FE3"),/*#__PURE__*/React.createElement("li",null,"\u8F6E\u64AD\u56FE4"),/*#__PURE__*/React.createElement("li",null,"\u8F6E\u64AD\u56FE5"))),/*#__PURE__*/React.createElement("div",{className:"footer"},"Footer"));return element
}}const app = ReactDOM.createRoot(document.querySelector("#app"))
app.render(React.createElement(App,null))</script>
虚拟DOM的创建过程
我们通过 React.createElement 最终创建出来一个 ReactElement对象:
这个ReactElement对象是什么作用呢?React为什么要创建它呢?
原因是React利用ReactElement对象组成了一个JavaScript的对象树;
JavaScript的对象树就是虚拟DOM(Virtual DOM);
如何查看ReactElement的树结构呢?
我们可以将上面代码中的jsx返回结果进行打印;
**而ReactElement最终形成的树结构就是虚拟DOM (Virtual DOM) **;
虚拟DOM帮助我们从命令式编程转到了声明式编程的模式
React官方的说法:Virtual DOM 是一种编程理念。
在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象
我们可以通过
root.render
让 虚拟DOM 和 真实DOM同步起来,这个过程中叫做
协调
(Reconciliation);
这种编程的方式赋予了React声明式的API:
你只需要告诉React希望让UI是什么状态;
React来确保DOM和这些状态是匹配的;
你不需要直接进行DOM操作,就可以从手动更改DOM、属性操作、事件处理中解放出来;
版权归原作者 学全栈的灌汤包 所有, 如有侵权,请联系我们删除。