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

基于Window的React Hook导致Next.js侧边栏闪烁的解决方法

解决Next.js侧边栏导航闪烁问题

问题根源

你的Hook在组件挂载时,初始sidebarWidth固定设为SIDEBAR_WIDTH,而正确的宽度计算逻辑要等到useEffect执行后才触发。Next.js页面导航时组件会重新挂载,这就导致页面先渲染窄侧边栏,紧接着useEffect执行后切换到展开宽度,从而出现闪烁。

解决方案

直接在useState初始化时就根据当前窗口宽度设置正确的初始值,避免后续调整导致的闪烁。同时要兼容服务器端渲染(SSR)场景,因为服务器环境没有window对象。

修改后的完整代码

export const useSidebarWidth = () => {
  // 初始化时直接计算正确宽度,兼容SSR
  const initialSidebarWidth = typeof window !== 'undefined' 
    ? window.innerWidth < SIDEBAR_BREAKPOINT ? SIDEBAR_WIDTH : SIDEBAR_WIDTH_EXPANDED 
    : SIDEBAR_WIDTH; // 服务器端 fallback 值

  const [sidebarWidth, setSidebarWidth] = useState(initialSidebarWidth);

  const handleResize = () => {
    if (window.innerWidth < SIDEBAR_BREAKPOINT) {
      setSidebarWidth(SIDEBAR_WIDTH);
    } else {
      setSidebarWidth(SIDEBAR_WIDTH_EXPANDED);
    }
  };

  useEffect(() => {
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  const isExpanded = sidebarWidth === SIDEBAR_WIDTH_EXPANDED;

  return {
    sidebarWidth,
    isExpanded,
  };
};

优化说明

  1. 初始值计算:客户端初始化时直接根据窗口宽度判断,组件挂载就渲染正确的侧边栏宽度,避免后续状态变更导致的闪烁。
  2. SSR兼容:通过typeof window !== 'undefined'判断环境,服务器端返回默认的窄宽度,避免SSR报错。
  3. 简化逻辑:移除了不必要的useMemo,直接通过sidebarWidth判断展开状态,逻辑更简洁。

内容的提问来源于stack exchange,提问作者Pierre Olivier Tran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:25:51