You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件与模板重渲染差异:为何表现不同及二者区别?

嘿,这个问题抓得特别准——其实核心是React对**元素(Element)和组件(Component)**的处理逻辑,以及多次调用ReactDOM.render时的实例复用规则,咱们一步步理清楚:

1. 两种ReactDOM.render调用的重渲染差异根源

先拆解你提到的两种场景的本质:

  • 场景A:复用同一个元素对象
    比如你提前声明好元素:

    const template = <Counter />; // 这里创建了一个React元素对象
    ReactDOM.render(template, app);
    // 后续再次调用时传同一个对象
    ReactDOM.render(template, app);
    

    这时候每次传给ReactDOM.render的是同一个元素对象(引用地址不变)。React会识别出这是同一个根元素,于是复用已有的Counter组件实例,只会对比组件内部的虚拟DOM变化,只更新需要变动的元素——这就是你看到的“仅重渲染特定元素”。

  • 场景B:每次创建新的元素对象
    如果你每次调用都直接写:

    ReactDOM.render(<Counter />, app);
    // 后续再次调用还是重新创建元素
    ReactDOM.render(<Counter />, app);
    

    这里的<Counter />每次都会被编译成React.createElement(Counter),返回一个全新的元素对象(引用地址不同)。React在根节点做对比时,会认为这是一个“新的根元素”,于是先卸载旧的Counter组件实例(清空state、执行卸载生命周期),再挂载全新的Counter实例——整个组件树被重建,自然触发全量重渲染,也就是你看到的“重渲染整个应用”。

2. 组件(Component)和元素(你说的“模板”)的核心区别

很多人会混淆这两个概念,简单说:

  • 元素(Element):是React描述UI的最小单元,本质是普通JavaScript对象,由React.createElement生成(JSX是它的语法糖)。它记录了要渲染的内容:比如标签类型(div、Counter)、属性、子元素。元素是不可变的,一旦创建就不能修改,更新UI只能通过创建新的元素。
  • 组件(Component):是生成元素的“工厂”,可以是函数或者类。它接收props作为输入,返回一个元素对象。比如function Counter() { return <div>{count}</div>; },这个Counter就是组件,<Counter />就是调用这个工厂生成的元素。

换句话说,你说的“模板”其实就是元素对象,而“组件”是生成这个对象的逻辑。

3. 为什么提前声明元素实例会解决全量重渲染?

当你在外部声明const MyElement = <Counter />,这个变量保存了元素对象的引用。每次调用ReactDOM.render(MyElement, app)时,React拿到的都是同一个引用,就会复用之前的组件实例,保留state,只做局部的虚拟DOM diff和更新,自然只会重渲染变化的部分——这和React在组件内部通过setState更新UI的逻辑是一致的:对比新旧元素,局部更新。

内容的提问来源于stack exchange,提问作者Liam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:35:44