为何useEffect在window.innerWidth/innerHeight变化时未触发更新?
问题:监听窗口尺寸变化时,useEffect依赖window.innerWidth/innerHeight为何不触发更新?
我尝试在页面上显示屏幕尺寸,希望拖拽窗口改变尺寸时,页面上的尺寸能实时更新。我理解useEffect的依赖数组中值变化时会触发内部逻辑,但为何依赖window.innerWidth和window.innerHeight时,拖拽窗口改变尺寸却不触发更新?
我的代码如下:
const [currentWindowWidth, setcurrentWindowWidth] = useState( window.innerWidth, ); const [currentWindowHeight, setcurrentWindowHeight] = useState( window.innerHeight, ); useEffect(() => { setcurrentWindowHeight(window.innerHeight); setcurrentWindowWidth(window.innerWidth); }, [window.innerHeight, window.innerWidth]);
返回部分:
<h1> -- {currentWindowWidth}x{currentWindowHeight} </h1>
我在网上找到了可行的解决方案,但想明白自己的逻辑为何不成立:
const handleWindowSizeChange = () => { setcurrentWindowHeight(window.innerHeight); setcurrentWindowWidth(window.innerWidth); }; useEffect(() => { window.addEventListener("resize", handleWindowSizeChange); return () => { window.removeEventListener("resize", handleWindowSizeChange); }; }, []);
原因分析
- React的useEffect靠浅比较依赖项决定是否触发,而且只有组件重新渲染时,才会检查依赖项的变化。
window.innerWidth和window.innerHeight是浏览器原生属性,React不会主动监听它们的变化。只有组件自身状态、props改变,或者父组件重新渲染时,组件才会重新执行代码,此时才会读取这两个属性的最新值。- 拖拽窗口改尺寸时,组件的状态和props都没有变化,所以组件不会重新渲染,useEffect的依赖数组不会被重新检查,自然不会触发内部的状态更新逻辑。
正确方案的原理
使用resize事件监听的方案之所以可行,原因如下:
- 浏览器在窗口尺寸变化时会主动触发
resize事件,通过事件监听器能精准捕获到变化时机。 - 在事件回调中更新React状态,状态变化会直接触发组件重新渲染,页面就能显示最新的窗口尺寸。
- 空依赖数组
[]确保事件监听器只在组件挂载时绑定一次,卸载时移除,避免重复绑定导致的性能问题。
内容的提问来源于stack exchange,提问作者Ash Gharibyan
相关产品推荐
相关产品推荐

