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

如何通过useEffect实时更新窗口宽度值,而非仅浏览器刷新后更新

问题分析与解决方案

核心问题

  1. 依赖数组无效:React的useEffect依赖数组只能追踪组件内部的响应式值(比如state、props、useCallback/useMemo生成的值),window.innerWidth是原生DOM属性,React无法感知它的变化,把它放在依赖数组里完全不会触发useEffect重新执行。
  2. 初始状态未同步:组件挂载时没有主动执行checkMobile,导致isMobile初始值(false)可能和当前窗口实际宽度不符,只有刷新或resize时才会更新。
  3. 未清理监听:没有在组件卸载时移除resize监听,会导致内存泄漏,多次渲染后还可能出现重复监听的问题。

修正后的代码

const Header = ({ mobileSidebarToggle, toggleMobileSidebar }) => {
  const { sidebarToggle, toggleSidebar } = useContext(SidebarContext)
  const [isMobile, setIsMobile] = useState(false)

  // 用useCallback缓存函数,避免每次渲染重新创建
  const checkMobile = useCallback(() => {
    // 简化逻辑,直接判断赋值
    setIsMobile(window.innerWidth < 1280)
  }, [])

  useEffect(() => {
    // 挂载时立即执行一次,同步初始窗口状态
    checkMobile()
    // 添加resize监听
    window.addEventListener('resize', checkMobile)
    // 组件卸载时移除监听,防止内存泄漏
    return () => {
      window.removeEventListener('resize', checkMobile)
    }
  }, [checkMobile]) // 依赖缓存后的checkMobile,确保监听函数稳定

  // 你的其他组件逻辑...
}

关键修正点说明

  • useCallback包裹checkMobile:保证函数引用稳定,避免组件每次渲染时都创建新的checkMobile,导致useEffect重复移除/添加监听。
  • 挂载时主动调用checkMobile:解决刷新后初始状态与实际窗口宽度不一致的问题。
  • 添加清理函数:组件卸载时移除resize监听,避免内存泄漏。
  • 简化状态更新逻辑:直接用window.innerWidth < 1280作为setIsMobile的参数,替代冗余的if-else判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:30:48