React父子组件重渲染行为异常问题咨询
React父子组件重渲染异常问题解答
问题场景
以下代码中,首次点击按钮时父组件和子组件都会重渲染,但第二次点击时只有父组件重渲染,后续点击则无任何变化:
import { useState } from "react"; const Footer = () => { const [sample, setSample]= useState("hello"); console.log("parent") return ( <> <Child sample={sample} setSample={setSample} /> </> ); }; export default Footer; const Child = ({sample,setSample}) => { console.log("child") return <div> <h1>{sample}</h1> <button onClick={()=>setSample("hi")}> Click me </button></div> }
1. 为何第二次点击时,state值未发生变化但父组件仍会重渲染,子组件不会?
- 父组件重渲染:调用
setSample("hi")时,React会先将更新请求加入队列,触发父组件进入重渲染流程。虽然最终对比新旧state发现值都是"hi",不会更新DOM,但父组件的函数体还是会执行一次(所以console.log("parent")会输出)。 - 子组件不重渲染:React默认会对组件进行浅比较优化,对比子组件的props是否变化。第二次点击后,父组件传给子组件的
sample值还是"hi",setSample是useState返回的稳定函数引用(每次渲染都一样),props没有任何变化,因此子组件会被跳过重渲染。
2. 为何第三次及之后的点击不会触发父组件重渲染?
React内部有重复更新的优化机制:当连续多次调用setter传入和当前state完全相同的值时,第一次(第二次点击)的更新会触发重渲染,但后续相同的更新请求会被直接忽略——React会检测到新值和当前state、以及最近一次的更新值完全一致,不会将其加入更新队列,自然不会触发父组件的重渲染流程。
内容的提问来源于stack exchange,提问作者Rohit Chand
相关产品推荐
相关产品推荐

