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

React仅首页导航栏滚动变色异常:路由切换后仍变化

路由切换后Header导航栏样式异常问题

组件代码

React状态与逻辑部分

const [small, setSmall] = useState(false)
    
console.log(window.location.pathname)
console.log(window.location.pathname === '/')

useEffect(() => {
  
  if (typeof window !== "undefined") {
    if(window.location.pathname === '/'){
      window.addEventListener("scroll", () =>
      setSmall(window.scrollY > 640),
    
      );
    }
       
  }
}, []);

HTML部分

<nav className={`padding-280px ${ small  ? "colorful" : "transparent"}`}

问题描述

处于非根路由(window.location.pathname !== '/')时,控制台已确认路径不等于根路径,但Header导航栏仍会随着滚动改变样式(small状态被修改)。

解决建议

  • 重置状态+监听路由变化+清理监听
    原代码只在组件挂载时判断路径并添加滚动监听,路由切换后组件不会重新挂载,旧的监听仍在运行,会持续修改small状态。可以借助React Router的useLocation钩子监听路由变化:

    import { useLocation } from 'react-router-dom';
    
    const location = useLocation();
    const [small, setSmall] = useState(false);
    
    useEffect(() => {
      const handleScroll = () => setSmall(window.scrollY > 640);
    
      if (typeof window !== "undefined") {
        // 先移除旧监听,避免重复绑定
        window.removeEventListener("scroll", handleScroll);
    
        if (location.pathname === '/') {
          window.addEventListener("scroll", handleScroll);
          // 切回根路由时,同步当前滚动位置的状态
          setSmall(window.scrollY > 640);
        } else {
          // 非根路由直接重置为透明样式状态
          setSmall(false);
        }
      }
    
      // 组件卸载时清理监听
      return () => {
        if (typeof window !== "undefined") {
          window.removeEventListener("scroll", handleScroll);
        }
      };
    }, [location.pathname]); // 路由变化时重新执行副作用
    
  • 直接在渲染层判断路径与滚动状态
    不需要依赖small状态,直接在className中结合当前路径和滚动值判断样式,从根源避免状态异常:

    const [scrollY, setScrollY] = useState(0);
    
    useEffect(() => {
      const handleScroll = () => setScrollY(window.scrollY);
      window.addEventListener("scroll", handleScroll);
      return () => window.removeEventListener("scroll", handleScroll);
    }, []);
    
    <nav className={`padding-280px ${window.location.pathname === '/' && scrollY > 640 ? "colorful" : "transparent"}`}
    
  • 核心注意点
    任何时候添加全局事件监听,都要在组件卸载或相关依赖变化时移除监听,否则会导致内存泄漏和状态不受控的问题。

内容的提问来源于stack exchange,提问作者Y U K I M U R A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:40:25