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

React中Link标签onClick先执行再触发to跳转的需求问题

当前使用react-scroll的<Link>组件实现导航时,遇到执行顺序异常:需求是点击时先调用getElementId展开折叠菜单,再触发滚动定位到目标DOM,但现有代码会优先执行滚动,此时菜单未展开导致无法找到目标元素。

解决思路

放弃<Link>的自动滚动逻辑,手动控制执行顺序:

  • 移除<Link>的to属性,避免自动触发滚动
  • 在点击事件中先执行菜单展开逻辑,等DOM更新完成后,再调用react-scroll的scroller工具手动触发滚动

代码实现

首先导入react-scroll的scroller工具:

import { scroller } from 'react-scroll';

修改getPreviewMenuChildren方法:

@autobind
getPreviewMenuChildren(element: any, parent: any) {
  let menuItem = undefined;

  // 统一处理点击事件逻辑
  const handleMenuItemClick = () => {
    // 第一步:执行折叠菜单展开操作
    this.getElementId(!!parent ? [element.id, parent.id] : [element.id]);
    // 第二步:等待DOM更新完成后触发滚动(requestAnimationFrame确保渲染周期结束)
    requestAnimationFrame(() => {
      scroller.scrollTo(element.id, {
        spy: true,
        smooth: true
        // 可根据需求添加offset等额外滚动配置
      });
    });
  };

  if (element["children"].length > 0) {
    menuItem = (
      <div>
        <li>
          <Link onClick={handleMenuItemClick} spy={true} smooth={true}>
            {element.title}
          </Link>
        </li>
        <ul>
          {element["children"].map((child: any) => 
            this.getPreviewMenuChildren(this.state.items[child], element)
          )}
        </ul>
      </div>
    );
  } else {
    menuItem = (
      <li>
        <Link onClick={handleMenuItemClick} spy={true} smooth={true}>
          {element.title}
        </Link>
      </li>
    );
  }
  return menuItem;
}

关键说明

  • requestAnimationFrame用于等待当前渲染周期结束,确保菜单展开后的DOM已完成更新,此时执行滚动就能正确找到目标元素
  • 手动调用scroller.scrollTo完全替代<Link>的to属性功能,同时保留原有滚动配置(spy、smooth)
  • 抽离点击事件为单独函数,提升代码可读性与可维护性

内容的提问来源于stack exchange,提问作者Jeffrey Andres Guette Sanguino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:23:33