首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau
百百 BLOG
首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau

Kurau Blog

「隨心而寫,真真假假,都是我」

一個記錄生活、輸出興趣的個人空間。
遊戲、影視、閱讀、學習……每一段體驗都值得留下文字。

頁面導覽

  • 學習紀錄
  • 遊戲心得
  • 影視Life
  • 書單
  • 委託作品與二創
  • Kurau
  • 合作邀請

找到我

歡迎來 Discord 找我聊天!

“曾經發生的事不可能忘記,只是暫時想不起來而已。”-《神隱少女》

© 2026 Kurau All rights reserved

前端框架

React-Router-Dom V6 Anchor Link

By Kurau·2023-03-20·Updated 2026-05-09·3 分鐘閱讀

React Router v6 Anchor Link

TL;DR
React Router v6 原生不支援 hash link 的捲動行為(<Link to="/about#team"> 不會自動捲到 #team)。用 react-router-hash-link 套件解決,支援 smooth scroll 跟跨頁 hash。

為什麼 v6 不支援?

React Router 是 SPA router,負責路由切換但不負責瀏覽器原生 anchor 行為。瀏覽器原生的 <a href="#section"> 行為依賴 頁面元素已經渲染,SPA 切頁時 React 還沒掛載目標元素,所以 #section 找不到。

// ❌ 不會自動捲到 #team
<Link to="/about#team">關於 - 團隊</Link>
tsx

解法:react-router-hash-link

npm install react-router-hash-link
npm install --save-dev @types/react-router-hash-link
bash
import { HashLink } from 'react-router-hash-link';

// 基本用法:跳到同一頁面的某個區塊
<HashLink to="/#section1">跳到 Section 1</HashLink>

// 跨頁面 hash 導航
<HashLink to="/about#team">關於我們 - 團隊</HashLink>

// 加 smooth scroll
<HashLink to="/#section2" smooth>
  平滑捲動到 Section 2
</HashLink>
tsx
Prop說明
to目標路徑 + #anchor(支援跨頁)
smooth平滑捲動(等同 scrollIntoView({ behavior: 'smooth' }))
scroll自訂捲動函式 (el) => el.scrollIntoView(...)
elementId替代 hash 的方式(直接給 ID)

套件做了什麼

簡化版內部邏輯:

import { useLocation, Link } from 'react-router-dom';
import { useEffect } from 'react';

function HashLink({ to, smooth, ...rest }) {
  return (
    <Link
      to={to}
      {...rest}
      onClick={(e) => {
        // 路徑切換後等下一個 tick 找元素 + 捲動
        setTimeout(() => {
          const id = to.split('#')[1];
          const el = document.getElementById(id);
          el?.scrollIntoView({ behavior: smooth ? 'smooth' : 'auto' });
        }, 0);
      }}
    />
  );
}
tsx

重點是 setTimeout(..., 0),等 React 渲染完目標元素再去找。


自己實作(不裝套件)

如果不想多裝一個套件,可以自己寫個 hook:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function useScrollToHash() {
  const { hash } = useLocation();

  useEffect(() => {
    if (!hash) return;
    const id = hash.replace('#', '');
    const el = document.getElementById(id);
    el?.scrollIntoView({ behavior: 'smooth' });
  }, [hash]);
}

// 在 root component 用
function App() {
  useScrollToHash();
  return <Routes>...</Routes>;
}
tsx

缺點:跨頁面跳轉時,目標頁面 component mount 完成的時機可能晚於 hook,要加 setTimeout 或 useLayoutEffect 配合。直接用 react-router-hash-link 比較穩。


Next.js 對等做法

Next.js 跟 React Router 不一樣,<Link href="/about#team"> 會 自動捲動。但 SSR 後若元素還沒 hydrate 完,可能也需要等 hydration:

import Link from 'next/link';

<Link href="/about#team" scroll>
  關於 - 團隊
</Link>
tsx

scroll prop 是 true 為預設(會自動捲),設 false 才會關掉。


smooth scroll 的瀏覽器支援

/* 全頁啟用 smooth scroll */
html {
  scroll-behavior: smooth;
}
css

所有現代瀏覽器都支援(Chrome 61+ / Firefox 36+ / Safari 15.4+)。直接 CSS 一行解決就不用 JS。但要避免動畫被 prefers-reduced-motion 使用者打擾:

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
css

目錄

    ◆ 相關文章

    • 新版的react-router-dom 與 tsconfig.json

      2026-05-09
    • Ladle 前端測試工具

      Ladle 前端測試工具

      2026-05-09
    • Human套件教學

      Human套件教學

      2026-05-09
    • HTML React 打字機效果

      2026-05-09
    ← 上一篇react-app-env.d.ts下一篇 →React-Use套件

    ◆ 關於作者

    Kurau

    個人寫作 / 創作的 SoT,記錄遊戲、影視、學習與生活。

    更多 Kurau 的文章