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

React路由切换后侧边栏函数触发TypeError报错求助

解决方案

问题根源

当路由切换到/signin时,Leftsidebar组件已被卸载,但之前通过$(window).on绑定的滚动、resize事件并未移除。触发这些事件时,updateSidebarPosition函数会尝试获取不存在的footer元素(AuthLayout中无Footer组件),调用offset().top时就会抛出Cannot read properties of undefined (reading 'top')错误。你之前仅判断了侧边栏元素的存在,未处理Footer不存在的情况,因此无效。

修复步骤

  1. 组件卸载时移除事件监听:在Leftsidebar组件中添加componentWillUnmount钩子,移除绑定在window上的事件,避免组件卸载后事件仍被触发。
  2. 同时判断侧边栏和Footer元素是否存在:在updateSidebarPosition函数开头,检查侧边栏和Footer元素是否存在,只要有一个不存在就直接终止函数执行。
  3. 修正事件绑定的命名空间:你之前绑定resize事件时用了scroll.resize命名空间,应改为resize.updateSidebar,确保后续能精准移除事件。

修正后的代码

componentDidMount() {
  const $ = window.$;
  const leftsidebar = $("#left-sidebar");
  
  function updateSidebarPosition() {
    // 先判断侧边栏和Footer是否存在,不存在直接返回
    if (!leftsidebar.length || !$("footer").length) {
      return;
    }
    
    var footerTop = $("footer").offset().top;
    var sidebarHeight = leftsidebar.outerHeight();
    var stopPoint = footerTop - sidebarHeight - 54;

    if ($(window).scrollTop() >= stopPoint) {
      leftsidebar.css({
        position: "absolute",
        top: stopPoint + 54 + "px",
      });
    } else {
      leftsidebar.css({
        position: "fixed",
        top: "56px",
      });
    }
  }

  // 初始化调用
  updateSidebarPosition();

  var isScrolling = false;
  // 保存事件处理器引用,方便后续移除
  const scrollHandler = function () {
    if (!isScrolling) {
      isScrolling = true;
      window.requestAnimationFrame(function () {
        updateSidebarPosition();
        isScrolling = false;
      });
    }
  };
  
  const resizeHandler = function () {
    updateSidebarPosition();
  };

  // 绑定事件并添加命名空间
  $(window).on("scroll.updateSidebar", scrollHandler);
  $(window).on("resize.updateSidebar", resizeHandler);

  // 将处理器挂载到组件实例上,供卸载时使用
  this.scrollHandler = scrollHandler;
  this.resizeHandler = resizeHandler;
}

// 组件卸载时移除事件监听
componentWillUnmount() {
  const $ = window.$;
  $(window).off("scroll.updateSidebar", this.scrollHandler);
  $(window).off("resize.updateSidebar", this.resizeHandler);
}

额外优化建议

尽量避免在React中使用jQuery操作DOM,推荐使用React的createRef(类组件)或useRef(函数组件)获取DOM元素,用原生JS实现位置计算,更符合React设计理念:

// 类组件示例
constructor(props) {
  super(props);
  this.sidebarRef = React.createRef();
}

componentDidMount() {
  const sidebar = this.sidebarRef.current;
  const footer = document.querySelector("footer");
  
  function updateSidebarPosition() {
    if (!sidebar || !footer) return;
    
    const footerTop = footer.getBoundingClientRect().top + window.scrollY;
    const sidebarHeight = sidebar.offsetHeight;
    const stopPoint = footerTop - sidebarHeight - 54;
    const scrollTop = window.scrollY;

    if (scrollTop >= stopPoint) {
      sidebar.style.position = "absolute";
      sidebar.style.top = `${stopPoint + 54}px`;
    } else {
      sidebar.style.position = "fixed";
      sidebar.style.top = "56px";
    }
  }

  // 事件绑定与移除逻辑类似,用原生addEventListener/removeEventListener
}

// render中绑定ref
<div ref={this.sidebarRef} id="left-sidebar">
  {/* 侧边栏内容 */}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:45:57