createElement 和 cloneElement 有什么区别?
React.createElement 和 React.cloneElement 是 React 核心 API 中最容易混淆的两个方法,但它们的作用其实完全不同。
React.createElement()
用于创建一个新的 React 元素(VNode)
这是 React 在底层用来创建虚拟 DOM 的核心函数。
当你写 JSX 时,其实都会被编译成 React.createElement() 调用。
示例
// JSX 写法
const element = <div className="box">Hello</div>;
// 实际等价写法
const element = React.createElement('div', { className: 'box' }, 'Hello');
参数说明
React.createElement(type, props, ...children)
| 参数 | 含义 |
|---|---|
type |
组件类型(标签名或组件) |
props |
元素属性对象 |
children |
子节点 |
React.cloneElement()
用于“克隆”一个已有的 React 元素,并在此基础上修改 props、children 等。
它不会重新创建一个新的类型的节点,而是基于现有的 React 元素(通常是子元素)复制一份。
示例
const element = <Button type="primary">提交</Button>;
const newElement = React.cloneElement(element, { type: 'danger' }, '删除');
结果:
-
保留原来的 Button 组件类型。
-
修改了 type 属性为 'danger'。
-
替换了子内容为 '删除'。
核心区别对比
| 对比项 | React.createElement |
React.cloneElement |
|---|---|---|
| 作用 | 创建新元素 | 基于已有元素复制一份并修改 |
| 输入 | 标签或组件类型 | 一个已有的 React 元素 |
| 输出 | 新的 React 元素 | 修改后的 React 元素 |
| 典型场景 | JSX 编译底层实现 | 父组件动态修改子组件的 props |
| 是否依赖原元素 | 否 | 是 |
| 是否改变类型 | 可以创建任意类型 | 类型与原元素相同 |
典型应用场景
createElement — JSX 底层机制
你平时写的 JSX:
<div className="box">Hello</div>
其实 React 编译后执行的是:
React.createElement('div', { className: 'box' }, 'Hello');
cloneElement — 修改子组件属性
比如父组件想统一给所有子组件注入 onClick 事件:
function Parent({ children }) {
return (
<div>
{React.Children.map(children, child =>
React.cloneElement(child, { onClick: () => alert('clicked!') })
)}
</div>
);
}
// 使用
<Parent>
<Button>按钮1</Button>
<Button>按钮2</Button>
</Parent>;
这样两个 Button 都自动获得了点击事件。
总结记忆口诀:
- createElement:无中生有(从类型生成新元素)
- cloneElement:有中生变(复制已有元素并改属性)
浙公网安备 33010602011771号