You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中用useEffect监听window.innerWidth重渲染页面及代码问题排查

代码存在的问题
  • 依赖项不具备响应性:window.innerWidth 是浏览器提供的原生属性,不属于React的响应式状态,放在useEffect的依赖数组中无法被React感知变更,因此这段useEffect只会在组件首次挂载时执行一次,后续窗口宽度变化完全不会触发回调,达不到实时监听的效果。
  • 边界条件遗漏:两个判断分支仅覆盖了窗口宽度小于800px、大于800px的场景,当宽度刚好等于800px时没有任何逻辑触发,body的display属性会保留上一次的设置值,可能出现不符合预期的展示结果。
  • 直接操作全局DOM不符合开发规范:直接修改body的样式属于全局操作,既不符合React状态驱动UI的设计理念,也容易和其他修改body样式的逻辑产生冲突,后续排查问题成本较高。
修复方案

如果你需要用JS实现尺寸监听,首先需要绑定窗口的resize事件来同步更新响应式状态,示例代码如下:

import { useState, useEffect } from 'react';

function YourComponent() {
  // 定义响应式的窗口宽度状态
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => {
      setWindowWidth(window.innerWidth);
    };
    // 监听窗口resize事件
    window.addEventListener('resize', handleResize);
    // 组件卸载时移除事件监听,避免内存泄漏
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  useEffect(() => {
    console.log("am called");
    if (windowWidth < 800) {
      document.body.style.display = "none";
    } else {
      // 覆盖等于、大于800px的所有场景
      document.body.style.display = "block";
    }
  }, [windowWidth]);

  // 组件其他逻辑
  return <></>;
}

提示:如果对性能要求较高,可以给handleResize函数加上节流处理,避免窗口拖动过程中频繁触发状态更新

如果只是需要实现小于800px时隐藏页面的效果,更推荐直接使用CSS媒体查询实现,性能远高于JS监听:

@media (max-width: 799px) {
  body {
    display: none;
  }
}

内容的提问来源于stack exchange,提问作者tedGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:06:05