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

react-router-dom NavLink无法跳转至指定section id解决方法

问题原因

React Router v6 版本默认不会自动处理hash锚点的滚动逻辑:点击带hash的NavLink时,仅会更新URL的hash字段,不会自动定位到对应id的DOM节点;如果服务端未配置BrowserRouter的路由回退规则,还会触发不必要的服务端请求。

实现步骤

1. 给目标区块配置对应id

首先确保四个页面对应区块的最外层DOM设置了和hash匹配的id属性,示例:

// Intro.js 最外层容器
<section id="intro">
  {/* 原有About内容 */}
</section>

// Skills.js(代码中引入命名为Services)最外层容器
<section id="skills">
  {/* 原有Skills内容 */}
</section>

// Works.js 最外层容器
<section id="works">
  {/* 原有Works内容 */}
</section>

// Contact.js 最外层容器
<section id="contact">
  {/* 原有Contact内容 */}
</section>

2. 优化NavLink的to属性写法

把原来拼接字符串的hash写法改为对象形式,避免路径拼接错误,修改后的Navbar.js代码:

// Navbar.js
import React from "react";
import "./Navbar.css";
import { NavLink } from "react-router-dom";

const Navbar = () => {
    return (
        <nav>
            <div className='container spaceB flex'>
                <div className='leftSide'>
                    <NavLink className='navLink' to="/">
                        <h1 className='logoH'>{"<Rajib/>"}</h1>
                    </NavLink>
                </div>
                <div className='rightSide'>
                    <ul className='flex'>
                        <NavLink className='navLink' to={{pathname: "/", hash: "#intro"}}>
                            <li>About</li>
                        </NavLink>
                        <NavLink className='navLink' to={{pathname: "/", hash: "#skills"}}>
                            <li>Skills</li>
                        </NavLink>
                        <NavLink to={{pathname: "/", hash: "#works"}} className='navLink'>
                            <li>Works</li>
                        </NavLink>
                    </ul>
                    <NavLink className='navLink' to={{pathname: "/", hash: "#contact"}}>
                        <button className='btn'>Contact</button>
                    </NavLink>
                </div>
            </div>
        </nav>
    );
};

export default Navbar;

3. 新增hash锚点滚动逻辑

在App组件中监听路由hash变化,自动滚动到对应元素,不需要修改现有路由结构,兼容所有React Router v6版本:

// App.js
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import "./App.css";
import Intro from "./components/common/Intro";
import Navbar from "./components/common/Navbar";
import Services from "./components/common/Skills";
import Works from "./components/common/Works";
import Contact from "./components/common/Contact";

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

    // 监听hash变化执行滚动
    useEffect(() => {
        if (location.hash) {
            const targetElement = document.querySelector(location.hash);
            if (targetElement) {
                targetElement.scrollIntoView({
                    behavior: "smooth", // 平滑滚动,可改为auto直接跳转
                    block: "start" // 滚动到元素顶部对齐视口
                });
            }
        }
    }, [location.hash]);

    return (
        <>
            <header>
                <Navbar />
            </header>
            <main>
                <Intro />
                <Services />
                <Works />
                <Contact />
            </main>
        </>
    );
}

export default App;

4. 解决点击链接触发服务端请求的问题

如果点击NavLink仍然触发服务端请求,检查开发/生产服务配置:使用BrowserRouter时,需要将所有路径请求都回退到index.html入口文件。

  • Vite项目在vite.config.js中添加配置:
export default defineConfig({
  // 其他原有配置
  server: {
    historyApiFallback: true
  },
  preview: {
    historyApiFallback: true
  }
})
  • Webpack项目在devServer配置中开启historyApiFallback: true即可。
效果说明

修改完成后点击导航栏按钮,页面会滚动到对应id的区块,不会触发服务端请求,URL会同步更新为带对应hash的形式。如果存在固定导航栏遮挡内容的情况,可以在滚动计算时减去导航栏高度调整最终滚动位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:30:55