为何使用包装组件可避免React子组件重复渲染?
为什么包装组件能阻止子组件重渲染
React组件重渲染的核心触发逻辑是:当组件自身状态更新,或接收的props发生变化时,会触发重渲染。父组件重渲染时,默认会带动所有直接子组件重渲染——哪怕子组件的props没变化,React也会默认执行渲染流程,除非做了针对性优化。包装组件能阻止子组件重渲染,核心是隔离了渲染上下文,具体可以拆解为以下两点:
1. 包装组件脱离父组件的状态依赖
包装组件是一个独立的组件,它不会接收父组件中频繁变化的状态作为props。当父组件因自身状态(比如每秒更新的计时器)重渲染时,包装组件的props没有发生变化,React就不会触发它的重渲染。
而子组件是作为包装组件的子元素存在的,只要包装组件不重渲染,子组件自然也不会被触发重渲染。
2. 对比两种写法的差异
直接渲染子组件(会重渲染)
function Parent() { const [count, setCount] = useState(0); useEffect(() => { const timer = setInterval(() => setCount(prev => prev + 1), 1000); return () => clearInterval(timer); }, []); // 父组件每秒重渲染,每次都会重新执行<Child />的调用,触发子组件重渲染 return <Child />; } function Child() { console.log("Child 重渲染了"); return <div>我是子组件</div>; }
这里Parent的状态每秒更新,<Child />作为直接子元素,会跟着父组件的渲染周期反复执行,最终触发子组件重渲染。
使用包装组件(不会重渲染)
function Parent() { const [count, setCount] = useState(0); useEffect(() => { const timer = setInterval(() => setCount(prev => prev + 1), 1000); return () => clearInterval(timer); }, []); // 包装组件WrappedChild不依赖父组件的变化状态,父组件重渲染时它不会跟着渲染 return <WrappedChild />; } // 独立的包装组件,内部固定渲染子组件 function WrappedChild() { console.log("WrappedChild 仅首次渲染"); return <Child />; } function Child() { console.log("Child 仅首次渲染"); return <div>我是子组件</div>; }
WrappedChild是独立的组件,它的props和状态都不随Parent的计时器变化,所以Parent重渲染时,WrappedChild不会被触发重渲染,子组件自然也不会跟着更新。
简单来说,包装组件相当于给子组件套了一层“隔离层”,让它脱离父组件的渲染周期,只在自身依赖的props/状态变化时才执行渲染。
内容的提问来源于stack exchange,提问作者hololo
相关产品推荐
相关产品推荐

