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

React导航链接点击不跳转锚点,强制更新报错页面冻结

React Router 锚点跳转不生效问题解决

问题根源

React Router 的Link组件在跳转同路由下的锚点时,只会更新 URL 的 hash 部分,不会触发浏览器默认的锚点滚动行为——因为路由组件(这里的Home)没有重新挂载,浏览器不会自动处理锚点定位。而手动输入 URL 能正常跳转,是因为页面完整加载时,浏览器会自动识别并滚动到对应锚点。

你之前尝试的强制重渲染方案完全错误:NavBar是函数组件,不存在this上下文,所以this.setState和this.forceUpdate会直接抛出Cannot read properties of undefined错误,同时强制重渲染也不是解决锚点问题的正确方向。

正确解决方案

方案一:监听路由变化自动滚动(推荐)

在路由组件Home中监听location的变化,当 hash 改变时主动滚动到对应元素,无需修改导航栏的Link逻辑:

// Home.jsx
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import Container from 'react-bootstrap/Container';
import NavBar from './NavBar';
import HomeContent from './HomeContent';
import Pricing from './Pricing';
import Footer from './Footer';

function Home() {
  const location = useLocation();

  useEffect(() => {
    // 提取URL中的锚点ID
    const targetId = location.hash.slice(1);
    if (targetId) {
      const targetElement = document.getElementById(targetId);
      if (targetElement) {
        // 平滑滚动到锚点
        targetElement.scrollIntoView({ behavior: 'smooth' });
      }
    } else {
      // 无锚点时滚动到页面顶部
      window.scrollTo({ top: 0, behavior: 'smooth' });
    }
  }, [location]); // 监听location变化触发执行

  return (
    <div>
      <Container fluid>
        <NavBar />
        <HomeContent />
      </Container>
      <Pricing />
      <Footer />
    </div>
  );
}

export default Home;

方案二:修改导航栏点击事件手动处理滚动

如果不想修改Home组件,可以在NavBar中用useNavigate钩子,跳转后手动触发滚动:

// NavBar.jsx
import { useNavigate } from 'react-router-dom';
import Navbar from 'react-bootstrap/Navbar';
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import { Link } from 'react-router-dom';

function NavBar() {
  const navigate = useNavigate();

  const handleAnchorJump = (targetPath) => {
    navigate(targetPath);
    // 延迟执行滚动,确保路由状态更新完成
    setTimeout(() => {
      const targetId = window.location.hash.slice(1);
      if (targetId) {
        const targetElement = document.getElementById(targetId);
        targetElement?.scrollIntoView({ behavior: 'smooth' });
      }
    }, 100);
  };

  return (
    <>
      <Navbar variant="dark" expand="lg">
        <Container>
          <Navbar.Brand onClick={() => handleAnchorJump('/home')} as={Link} to="/home">
          </Navbar.Brand>
          <Navbar.Toggle aria-controls="basic-navbar-nav" />
          <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="justify-content-end flex-grow-1 pe-3">
              <Nav.Link onClick={() => handleAnchorJump('/home')} as={Link} to="/home">
                Home
              </Nav.Link>
              <Nav.Link onClick={() => handleAnchorJump('/home#pricing')} as={Link} to="/home#pricing">
                Pricing
              </Nav.Link>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
    </>
  );
}

export default NavBar;

额外说明

  • 移除你之前写的handleClick函数:函数组件没有this,这类写法完全无效;
  • 两种方案都支持平滑滚动,若不需要可以去掉behavior: 'smooth'参数;
  • 无需使用withRouter,React Router v6 中函数组件直接用useLocation、useNavigate等钩子即可获取路由上下文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:48:24