掌握React.createElement面试高频考点,快速说清JSX转换、React element对象、组件与DOM区别,面试追问也能稳接住,点击看完整答案。
大多数在 React.createElement 面试题上卡住的候选人,其实已经会 JSX 了。这就是讽刺之处。他们写过成百上千个组件,懂 props,知道 hook 的作用——可一旦面试官问一句“React.createElement 实际上返回什么?”,答案往往在十秒内就开始含糊。这篇指南先给你一个干净利落的 30 秒答案,再给你刚好足够的补充深度,让你在追问时也能稳稳接住。
先给 30 秒答案,不要先讲课
听起来很自信,但不像背答案的回答
在 React.createElement 面试里,可以这样回答,尽量接近下面这段:
“JSX 是语法糖,Babel 会在 React 运行之前把它编译成 React.createElement 调用。React.createElement 接收一个 type——可以是像 'div' 这样的字符串,也可以是函数或类组件——再加上一个 props 对象和任意 children,然后返回一个叫做 React element 的普通 JavaScript 对象。这个对象描述了屏幕上应该显示什么。React 的 reconciler 读取这些对象,并决定在真实 DOM 里创建、更新或移除什么。所以 React.createElement 负责构建描述;ReactDOM 负责处理页面。”
这段话不到 60 秒。它提到了 JSX、转换过程、返回对象和渲染路径,但没有陷进内部实现细节。面试官现在已经有了完整的 ذهن model,也有了清晰的追问起点。
为什么简短回答会显得不对劲
大多数候选人犯的结构性错误,是把这个问题当成介绍 React 历史的邀请。他们会先说“JSX 之所以被引入,是因为手写 React.createElement 太啰嗦”——等他们讲到函数实际返回什么时,面试官其实已经做出判断了。另一种失败方式是直接跳到 fiber 或 virtual DOM,听起来很厉害,但却绕过了题目真正问的基础定义。
真正要做的事,是在一小段里说清三件事:JSX 编译成 createElement,createElement 返回普通 element 对象,React 用这个对象更新 DOM。其他内容都属于追问范畴。
实战中会是什么样子
想象一个 60 秒的模拟面试场景。面试官问:“你能解释一下 React.createElement 是做什么的吗?”候选人用上面那段话回答——type、props、children、普通对象、reconciler。面试官继续问:“那 JSX 是组件吗?”
候选人完全不慌:“不是——JSX 是语法。它会编译成一个 createElement 调用。组件才是 JSX 可能在 type 参数里引用的函数或类,但它们属于不同层级。”
这个追问只需要五秒,因为前面的回答已经把术语体系建立起来了。React 关于 JSX 转换的文档 和 React elements 规范 都把这个区分当作基础——懂 React 的面试官也一样。
用 React.createElement 解释 JSX 转换,但不要把它讲成编译器导览
JSX 是快捷写法,不是 React 真正理解的东西
最常见的混淆是,JSX 给人的感觉太像 React 本身了——它出现在每个 React 文件里,看起来就像 UI 本身,也是你花最多时间写的东西。但 JSX 是编译时转换。等 React 的运行时代码真正执行时,每个 JSX 表达式都已经被 Babel 或 TypeScript 编译器转换成了 React.createElement 调用。React 从来没看到 JSX。它看到的只有函数调用。
这个区别——JSX 到 React.createElement——就是答案的核心。能把它说清楚,才算是真正理解了 React,而不只是会用 React。
实战中会是什么样子
看这段 JSX:
Babel 会把它编译成:
第一个参数是 type——这里是原生 HTML 标签,所以是字符串 `"button"`。第二个参数是 props 对象。第三个参数是子元素——文本字符串“提交”。如果有多个子元素,它们会成为额外的参数,或者放在 props.children 里。Babel REPL 可以让你直接粘贴 JSX,实时看到编译结果——这是把这个转换从“理论”变成“具体”的最快方式。
这在面试里为什么重要
如果你能清楚地追踪这个转换过程,你就不会像一个只背过定义的人,而会像一个真正理解流程的人。面试官的追问——“如果 type 是组件呢?”或者“children 最终去哪了?”——其实都能用你刚刚展示的同一个 mental model 回答。你不需要记新答案,只要把这条轨迹继续展开就行。
先描述 React element 对象,再给它贴别的标签
面试官真正想考的,是这个“普通对象”的模型
React.createElement 返回的是一个 React element 对象——一个普通 JavaScript 对象,不是 DOM 节点,不是组件实例,也不是什么神秘东西。这个对象有一个可预期的结构:`type` 字段、包含 children 的 `props` 字段、`key` 和 `ref`。在真实应用里 `console.log` 一个 React element,看到的就是这个。
这其实就是面试官问 createElement 时真正想确认的:你是否理解 React 处理的是 UI 的描述——element 对象——而不是直接操作 DOM。
实战中会是什么样子
在 React sandbox 里运行:
输出大致会像这样:
在面试回答里,真正重要的字段是 `type`、`props` 和 `children`(它在 props 里面)。`$$typeof` 这个符号是 React 用来区分元素和其他对象的安全机制——如果面试官继续追内部实现,可以提,但没必要一上来就讲。React 关于 elements 的源码级文档 对这个结构说明得很准确。
这里最容易犯的错
候选人常常把三件不同的事混在一起:React element 对象(描述要渲染什么的普通 JS 对象)、DOM element(React 渲染之后才存在的浏览器节点)和组件实例(React 在处理 class 组件时内部创建的东西)。这是三个不同层级。说“createElement 返回一个 DOM element”是错的。说“createElement 返回一个组件”也不对。最稳妥的回答永远是:它返回一个描述应该渲染什么的普通对象。
区分 React element、React component 和 DOM element
为什么这个混淆总是发生
当你写 `<MyButton onClick={fn} />` 时,你其实是在同时看到 JSX 语法、引用一个组件、并生成一个 element——全都在一行里。这个层级在视觉上压缩了,所以在脑子里也很容易被压缩。混淆不是因为粗心,而是因为结构本来就重叠。代码看起来像一个东西,实际上却代表三层。
实战中会是什么样子
原生标签示例:
函数组件示例:
在这两种情况下,`el` 都是普通对象。DOM element 还不存在。MyButton 也还没有执行。React element 和 component 的区别,取决于 `type` 字段装的是什么——原生标签是字符串,组件是函数或类——而 DOM element 是整个渲染流程的下游结果,根本不属于 createElement 本身。React 关于组件和 elements 的文档 明确划分了这个区别。
值得背下来的一个一句话区分
组件是函数或类。element 是 React.createElement 返回的普通对象。DOM element 是浏览器最终创建出来的节点。这是三种不同的东西,处在三个不同层级。
解释 React.createElement 传入函数或类时会发生什么
大多数候选人会一笔带过的部分
当 type 参数是函数组件或类组件时,React.createElement 不会调用这个函数,也不会实例化这个类。它只是记录引用。它返回的 element 对象会把 `type: MyButton` —— 也就是函数本身 —— 放进 type 字段里。之后在渲染阶段,React 的 reconciler 才会读取它,并决定下一步怎么处理。
实战中会是什么样子
函数组件路径:
类组件路径:
React 会在 reconciliation 期间调用函数或实例化类——不是在 createElement 期间。这也是为什么你可以创建 element 却不挂载它们,可以把它们作为 props 传递,或者存到 state 里,而不会触发任何渲染逻辑。
面试里最安全的追问回答
如果面试官问函数组件和类组件在 element 层面是否一样:是的,在 createElement 这一层它们是一样的——都会生成一个 element 对象,并把组件引用放在 type 里。区别只会在 React 处理这个 element 时出现:函数组件会被调用,类组件会被实例化并调用它的 render 方法。这个区别属于 React 的 reconciler,而不是 createElement 本身。
在说错话之前,先把 React.createElement 和 ReactDOM.createRoot 区分开
人们总爱把这两个不同的工作混成一个
这两个 API 都和把 UI 放到页面上有关,所以候选人很容易把它们混在一起。但它们做的事完全不同。React.createElement 构建描述——一个完全存在于 JavaScript 里的普通 element 对象。ReactDOM.createRoot 把 React 挂到真实的 DOM 容器上,并给你一个可以 render 的 root。一个负责描述;另一个负责挂载。
实战中会是什么样子
createElement 先执行,生成 element 对象。createRoot 后执行,把 React 连接到真实的 DOM 节点。root.render() 接收 element 对象并触发 reconciliation。它们是顺序关系,也是独立关系。React 18 的 createRoot 文档 说明了当前 API——如果你还在引用旧的 `ReactDOM.render`,请更新你的 mental model,因为使用 React 18 的面试官会注意到这一点。
这句能帮你避坑
“React.createElement 构建描述 UI 的 element 对象。ReactDOM.createRoot 把 React 挂载到 DOM 容器里。它们是不同的 API,做的是不同的工作——一个纯 JavaScript,一个会碰到浏览器。”
回答面试官真正会追问的问题
JSX 是组件吗?
不是——这个坑非常值得记住。JSX 是语法。它会编译成 React.createElement。组件才是 JSX 可能在 type 参数里引用的函数或类。你完全可以写出返回原生标签(`<div>`)的 JSX,而这时根本没有组件参与。把 JSX 和组件混为一谈,说明你没有把层级分开,而这正是这类问题想测试的内容。
什么是 element instance?
这个说法有点不严谨,面试官有时会故意这么问,看看你怎么接。React element 是一个普通对象——它不是被实例化出来的,没有方法,也不持有 state。“element instance”通常是在试探你是否理解:elements 是不可变的描述,而不是活的对象。最稳妥的回答是温和澄清:“React element 是一个普通对象,不是实例——它是对应该渲染内容的描述。component instance 则是 React 在处理类组件时内部创建的东西。”
如果 child 是组件而不是 DOM 标签,会发生什么?
element 对象里的 type 字段会从字符串变成函数或类引用。这是机械层面的答案。行为上的结果是,React 的 reconciler 现在需要调用或实例化这个 type,才能拿到下一层的 elements——它会沿着树继续递归,直到所有内容都解析成原生标签。这就是 React 为什么能组合组件:每个组件都会返回更多 elements,React 会不断拆开,直到得到一棵可以交给 DOM renderer 的字符串树。
把答案钉牢,别在压力下说混
那些“差一点对”的回答
最常见的两种“几乎对”的答案是:“JSX 就是组件”和“createElement 返回一个 DOM 节点”。这两句话都错,但错得很像真的——如果你没听仔细就会被带偏,这也正是面试官会继续追问的原因。只要你说了其中任何一句,后续追问会来得很快,而且不会太舒服。
实战中会是什么样子
在任何 React.createElement 面试之前,先大声练三句话:
- JSX 这句:“JSX 是语法糖,Babel 会在 React 运行之前把它编译成 React.createElement。”
- element 对象这句:“React.createElement 返回一个带有 type、props 和 children 的普通 JavaScript 对象——不是 DOM 节点。”
- 渲染这句:“React 的 reconciler 读取这些对象,而 ReactDOM 负责真正的 DOM 更新。”
按顺序把这三句话练到不需要停顿。这就是完整答案。这个指南里其他内容,都是追问时的弹药。
十秒自检法
练完之后,问自己四个问题:我有没有把 JSX 说成语法,而不是运行时东西?我有没有说 createElement 返回的是普通对象,而不是 DOM 节点?我有没有把组件(函数或类)和 element(对象)区分开?我有没有把 DOM 操作放到 ReactDOM,而不是 createElement 里?如果四个问题都能答“是”,这个回答就足够应对面试了。如果你说着说着有任何一个区分开始模糊,那就是你最该练的地方。
FAQ
Q: 用大白话怎么解释 React.createElement?面试里怎么在 30 秒内讲清楚?
React.createElement 是一个函数,它接收一个 type(标签名或组件)、一个 props 对象和 children,然后返回一个描述屏幕上应该显示什么的普通 JavaScript 对象。面试里可以这样说:“JSX 会编译成 React.createElement,而 React.createElement 返回一个普通对象——element——React 用它来判断应该渲染什么到 DOM 里。”
Q: JSX 编译之后,React.createElement 具体会产出什么?
它会产出一个普通 JavaScript 对象,至少包含 `type` 字段、`props` 字段(其中包含 children)、`key` 和 `ref`。这个对象有时被称为 React element。它不是 DOM 节点,也不是组件实例——它只是一个轻量级描述,说明屏幕上应该呈现什么。
Q: React element、React component 和 DOM element 有什么区别?
React component 是一个返回 elements 的函数或类。React element 是 React.createElement 返回的普通对象——对要渲染内容的描述。DOM element 是 React 处理这些描述并提交到页面后,真实存在的浏览器节点。三层,不同东西。
Q: React.createElement 接收函数组件和类组件时分别会发生什么?
在这两种情况下,createElement 都只是把引用记录到 element 的 `type` 字段里,然后返回 element 对象——它不会调用这个函数,也不会实例化这个类。React 的 reconciler 会在之后的渲染阶段做这件事:函数组件会被调用,类组件会被实例化并调用其 render 方法。
Q: 我平时主要写 JSX,为什么还要理解 React.createElement?
因为你写的每一个 JSX 表达式,本质上都是伪装过的 React.createElement。当某些地方出问题——比如 key 警告、意外重渲染、prop 没有传到——真正有助于你排查问题的 mental model,就是你能看到 createElement 调用长什么样,以及 element 对象里到底有什么。只会 JSX 而不理解 createElement,就像会用工具但没有地基。
Q: 面试官在基础定义之后通常还会问什么?
最常见的追问有这些:“JSX 是组件吗?”(不是,它是语法)、“返回的对象长什么样?”(type、props、children)、“element 和 component 有什么区别?”(对象 vs 函数/类)、“ReactDOM.createRoot 做了什么不同的事?”(把 React 挂到 DOM 上,不负责构建 elements)。把这四个问题搞清楚,基本就覆盖了大多数 React.createElement 的追问。
Q: 怎么避免把 JSX、组件和 element 混为一谈?
始终保持三层模型清晰:语法(JSX)、描述(element 对象)、浏览器节点(DOM element)。当你准备说“JSX 是……”或者“组件是……”的时候,先停一下,确认自己到底在说哪一层。JSX 是编译时语法。组件是函数或类。element 是 createElement 返回的普通对象。如果这三者定义清晰,就不会混淆。
Verve AI 如何帮助你准备 React.createElement 面试
React.createElement 面试最难的部分,不是知道定义,而是在真实压力下把它清楚地说出来,同时不把各层级说混。这是一种表现能力,不是记忆能力,而且只有在面对真实追问、反复练习时才能建立起来。
Verve AI Interview Copilot 正是为这个缺口而设计的。它会实时监听你回答时说了什么,并根据你实际说出的内容做出反应——不是预设好的提示。如果你在回答里把 element 和 component 混了,Verve AI Interview Copilot 会抓到这一点。如果你对 JSX 的解释滑到了运行时层面,它生成的追问也会反映出这个具体错误。Verve AI Interview Copilot 在练习时保持“隐身”,让训练阻力更小、反馈更精准。对于 React.createElement 这种“答案很短、追问树很宽”的概念,这类响应式练习正是缩小“懂知识”和“讲得像自己真的懂”之间差距的关键。
结论
你不需要把自己说得像 React runtime 工程师,才能通过 React.createElement 面试。你只需要足够准确,能清楚区分四件事而不乱:JSX 是编译时语法,React.createElement 返回普通 element 对象,component 是这个对象可能引用的函数或类,而 DOM element 只会在 React 渲染之后才存在。答案就是这些。本文里的所有内容,要么是答案本身,要么是应对追问的弹药。
现在就大声把三行版本练一遍——JSX 那句、element 对象那句、渲染那句——然后用第 7 节里的追问测试自己。如果你能不犹豫地回答“JSX 是组件吗?”和“element 对象长什么样?”,那你就准备好了。
Verve AI
内容
