理解JSX 和虚拟 DOM
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理解JSX 和虚拟 DOM相关的知识,希望对你有一定的参考价值。
参考技术Ajsx和虚拟dom一直都是react面试中老生常谈的问题,但面试题背归背,只有把问题弄懂了才能转换成自己的真正的实力。
JSX 是一个 javascript 的语法扩展,在react项目中可以像这样声明一个变量。
所以JSX其实是React.createElement()的语法糖,JSX在编译时会被Babel编译为React.createElement方法。
这也是为什么在每个使用JSX的JS文件中,你必须显式的声明
不过,React 17 在 React 的 package 中引入了两个新入口,这些入口只会被 Babel 和 TypeScript 等编译器使用。新的 JSX 转换不会将 JSX 转换为React.createElement,而是自动从 React 的 package 中引入新的入口函数并调用。
React.createElement内部会调用ReactElement函数最后返回一个对象。
ReactElement最终会返回一个包含组件数据的js对象,这就是经常说的虚拟dom对象,也是一个react元素,其中$$typeof属性被赋值为REACT_ELEMENT_TYPE的常量标记这个对象是一个合法的react元素。
并且react提供了全局API用于校验对象是否为合法的react元素
$$typeof 属性也起到了防止 XSS 攻击的作用。
如果服务器允许用户储存任意的 JSON 数据的情况下。那么就可以手动构建 React Element 对象传入到元素中。例如:
REACT_ELEMENT_TYPE值的定义
使用 Symbol 类型是因为 JSON 中无法传递 Symbol。React 会检查 element.$$typeof 然后拒绝处理非法的元素,这样就可以规避这个问题。
使用class component或者function component的时候component都会被当作React.createElement函数中的第一个参数type传入
注意点
如果自定义组件的命名不是大写开头的话,babel只会转换成普通的标签,也称为HostComponent.
结果type会变成"funcComp"而不是funcComp组件,这也是react自定义组件为什么要大写开头的原因。
从上面的内容我们可以发现,JSX是一种描述当前组件内容的数据结构,他不包含组件schedule、reconcile、render所需的相关信息。
比如如下信息就不包括在JSX中:
所以,在组件mount时,Reconciler根据JSX描述的组件内容生成组件对应的Fiber节点。
在update时,Reconciler将JSX与Fiber节点保存的数据对比,生成组件对应的Fiber节点,并根据对比结果为Fiber节点打上标记。
以上是关于理解JSX 和虚拟 DOM的主要内容,如果未能解决你的问题,请参考以下文章