虚拟Dom
用JavaScript对象的方式描述dom结构。
可以通过 createElement方法(一般简称h是Hyperscript缩写)创建虚拟dom。
function h(
type: string | Component,
props?: object | null,
children?: Children | Slot | Slots
): VNode
相关考题:
Q1: 使用虚拟DOM的好处是什么?
通过 Diff 算法 和 批量更新(Batching) 来最小化重绘重排的次数。
补充: 但在某些极端高性能场景下(如仅仅修改一个数值),直接操作原生 DOM 比 VDom 更快,因为 VDom 还有额外的 Diff 计算开销。
让ui框架与平台解耦。在浏览器环境渲染成dom,在移动端(React Native)渲染成原生控件,在服务器端渲染成字符串。
Q2: createRoot、createElement、render三个方法的区别是什么
createElement负责创建VNode,所有的JSX都会被编译器编译成createElement函数调用,最终生成JavaScript对象。
createRoot方法是React 18新api,负责创建React渲染根。它是开启 React 18 并发模式 (Concurrent Mode) 的大门。只有通过 createRoot 创建的应用,才能使用 useTransition、Suspense 等高级功能。
render是root对象的方法,负责将虚拟 DOM 转换成真实的 DOM 节点,并插入到页面中。
JSX
为了迎合声明式UI做的JavaScript语法扩展,实现用写HTML的方式描述虚拟Dom。
编译工具(如Babel)可以把Jsx编译成React.createElement(type, config, children),其执行结果是一个普通的 JavaScript 对象(即虚拟 DOM)。
相关考题:
Q1: 为什么 JSX 组件名必须以大写字母开头?
因为要让 JSX 编译器区分原生 HTML 标签和自定义组件。小写则编译成字符串,大写则当做变量引用。小写时_jsx('div', ...),大写时 _jsx(MyComponent, ...)
Q2: JSX 如何防止 XSS(跨站脚本攻击)
React在渲染之前会转义所有JSX中的字符串。如果一定要渲染一段HTML字符串可以通过该方法dangerouslySetInnerHTML={{ __html: yourHtmlString }}
Q3: 为什么 JSX 只能有一个根节点(或者必须用 Fragment)?
因为 JSX 最终会被转化成一个函数调用。一个函数不能同时返回两个对象。