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

React将组件作为Props传递时为何不随父组件状态更新重渲染

import * as React from 'react'
import ReactDOM from 'react-dom'
function Logger(props) {
  console.log(`${props.label} rendered`)
  return null
}
function Counter(props) {
  const [count, setCount] = React.useState(0)
  const increment = () => setCount(c => c + 1)
  return (
    <div>
      <button onClick={increment}>The count is {count}</button>
      {props.logger}
    </div>
  )
}
ReactDOM.render(
  <Counter logger={<Logger label="counter" />} />,
  document.getElementById('root'),
)
问题解答

核心逻辑是React元素的创建时机直接决定了组件是否会跟随宿主组件重渲染,对应你的三个问题逐一解释:

  • 为什么每次更新count状态时,Logger组件不会触发重渲染?
    React触发组件重渲染的核心前提是:组件对应的React元素发生变化,或是组件自身状态/消费的Context发生变更。你代码里的<Logger label="counter" />在ReactDOM.render调用时就已经创建完成,相当于提前生成了固定的组件快照传给Counter。当Counter内部count更新触发自身重渲染时,只是复用了之前传入的Logger元素,这个元素本身没有任何变更,所以React不会重新执行Logger的渲染逻辑,自然不会输出打印日志。
  • 这种将组件作为props传递的方式是如何避免Logger函数组件的props对象发生变化的?
    Logger的props(也就是{label: "counter"})是在创建<Logger />元素时就被固定下来的,这个创建动作发生在Counter组件的外部,和Counter的内部状态完全无关。这段代码中外层只有一次ReactDOM.render调用,没有触发外层重渲染的逻辑,所以Logger的props对象永远不会发生变化,自然不会触发重渲染。
  • 为什么Counter组件每次重渲染时,不会创建新的Logger props对象?
    核心区别是<Logger />的创建位置:你是把已经创建完成的元素作为props传给Counter,不是在Counter的函数体内部声明<Logger />。如果把<Logger label="counter" />直接写在Counter的return语句中,每次Counter重渲染都会执行一次React.createElement(Logger, {label: "counter"}),生成全新的React元素对象,对应的props对象也会是新的。但现在创建逻辑在Counter外部,Counter重渲染时只会读取传入的props.logger,不会重新执行创建逻辑,自然不会生成新的props对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:12:03