为何空依赖useEffect仍触发height/width更新与组件重渲染?
空依赖useEffect下窗口resize触发组件重渲染的原因解析
先看你的代码实现:
import * as React from "react"; // import "./style.css"; export default function App() { let [width, setWidth] = React.useState(window.innerWidth); let [height, setHeight] = React.useState(window.innerHeight); React.useEffect(() => { console.log("useEffect is called"); window.addEventListener("resize", () => { setHeight(window.innerHeight); setWidth(window.innerWidth); }); }, []); return ( <div> {/* <button onClick={handler}> Submit </button> */} <h1> {" "} {height},{width}{" "} </h1> </div> ); }
核心原因拆解
- 空依赖数组的
useEffect确实只在组件初始渲染后执行一次,你可以观察控制台的console.log输出,只会打印一次,这点你的理解没问题。它的作用仅仅是给window绑定了一次resize事件监听,后续不会重复执行这个回调。 - 窗口resize时,触发的是你绑定在
window上的resize事件处理函数,这个函数里调用了setHeight和setWidth来更新组件状态。而React的核心机制就是状态变化驱动组件重渲染,只要状态更新,组件就会重新渲染,UI上的height和width自然会同步更新。 - 这里有个容易忽略的问题:当前代码没有在组件卸载时移除resize事件监听,会造成内存泄漏。可以优化代码,在useEffect的返回函数中清理监听:
React.useEffect(() => { console.log("useEffect is called"); const handleResize = () => { setHeight(window.innerHeight); setWidth(window.innerWidth); }; window.addEventListener("resize", handleResize); // 组件卸载时移除事件监听 return () => window.removeEventListener("resize", handleResize); }, []);
内容的提问来源于stack exchange,提问作者Chandra Mohan Srivastava
相关产品推荐
相关产品推荐

