为何React中子组件状态变更会触发父组件重渲染?
子组件状态变更为何触发父组件重渲染?
实验背景
- 使用React 17.0(内置Fiber架构)
- 包含两个函数组件:
Agregator(父组件)和Counter(子组件) Counter使用useState钩子管理自身状态- 特殊写法:
Agregator并未通过JSX标签<Counter />渲染子组件,而是直接调用Counter()函数返回其结果 - 现象:点击
Counter的按钮更新状态时,控制台日志显示Agregator也发生了重渲染
实验代码
function Agregator() { console.log("render Agregator"); return Counter(); } function Counter() { const [count, setCount] = React.useState(0); const incCount = () => setCount((prev) => prev + 1); console.log("render Counter", count); return <button onClick={incCount}>{count}</button>; } ReactDOM.render(<Agregator />, document.getElementById("root"));
原因解释
你这种直接调用组件函数的写法,并没有让Counter成为独立的React组件实例——它本质上只是Agregator渲染逻辑的一部分,相当于把Counter的返回值当成了Agregator的渲染输出内容。
React的useState钩子是和当前组件的渲染上下文绑定的:当你在Agregator的执行过程中调用Counter()并创建useState状态时,这个状态实际上是属于Agregator的渲染上下文的。
因此,当调用setCount更新状态时,React会触发拥有该状态上下文的组件(也就是Agregator)重渲染;Agregator重新执行时,自然会再次调用Counter(),导致Counter也跟着重新执行,最终表现为两者都出现重渲染日志。
而正常使用<Counter />JSX标签渲染时,React会将Counter作为独立的组件节点挂载,它的状态属于自身的渲染上下文,状态变更只会触发自身重渲染,不会影响父组件。
内容的提问来源于stack exchange,提问作者bullet03
相关产品推荐
相关产品推荐

