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

React中HashRouter本地失效及锚点链接问题解决

问题解决方案

一、HashRouter本地无法运行的原因

你的项目部署在GitHub Pages的子路径/portfolio2/build下,而本地开发是在根路径/运行。使用HashRouter时未根据环境配置basename属性,导致本地路由解析和部署环境不匹配,从而无法正常工作。

二、让网站本地正常运行的方法

修改RouteSwitch组件,根据环境动态设置HashRouter的basename:

import { BrowserRouter, Routes, Route, HashRouter } from "react-router-dom";
import App from "../App";
import Admin from "./admin";

function RouteSwitch(){
  // 生产环境匹配部署子路径,开发环境用根路径
  const basename = process.env.NODE_ENV === 'production' 
    ? '/portfolio2/build' 
    : '';

  return (
      <HashRouter basename={basename}>
          <Routes>    
              <Route path="/" element={<App />} />
              <Route path="/admin" element={<Admin />} />
          </Routes>
      </HashRouter>
  );
}

export default RouteSwitch;

这样配置后,本地开发和GitHub Pages部署的路由解析逻辑会自动适配,两边都能正常运行。

三、恢复锚点链接功能的方法

HashRouter已使用URL中的#管理路由,直接用<Link to="#section">会被路由系统解析为路由路径,而非页面内锚点。可通过以下两种方法解决:

将Nav组件中的<Link>换成原生<a>标签,通过自定义事件阻止页面刷新并实现平滑滚动:

// Nav.js 修改后的代码
import "../styles/nav/nav.css";
import "../styles/nav/nav-ul.css";
import "../styles/nav/nav-li.css";
import "../styles/nav/nav-a.css";
import "../styles/nav/nav-imagem.css";
import "../styles/nav/nav-button.css";
import Tracos from "../images/tracos.png";

function Nav(){
    function showMenu(){
        let ul = document.querySelector(".nav__ul");
        if(ul.style.display===""){
            ul.style.display="flex";
        }else if(ul.style.display==="flex"){
            ul.style.display="";
        }
    }

    // 处理锚点跳转,阻止默认页面刷新
    const handleAnchorClick = (e, targetId) => {
        e.preventDefault();
        const element = document.getElementById(targetId);
        if(element){
            element.scrollIntoView({ behavior: 'smooth' });
        }
    }

    return (
        <nav className="nav">
            <button className="nav__button" onClick={ () => showMenu() }>
                <img className="nav__imagem" src={ Tracos } alt="" />
            </button>
            <ul className="nav__ul">
                <li className="nav__li">
                  <a 
                    className="nav__a" 
                    href="#cabecalho" 
                    onClick={(e) => handleAnchorClick(e, 'cabecalho')}
                  >
                    Início
                  </a>
                </li>
                <li className="nav__li">
                  <a 
                    className="nav__a" 
                    href="#quem-e" 
                    onClick={(e) => handleAnchorClick(e, 'quem-e')}
                  >
                    Quem é Priscila?
                  </a>
                </li>
                <li className="nav__li">
                  <a 
                    className="nav__a" 
                    href="#formacao" 
                    onClick={(e) => handleAnchorClick(e, 'formacao')}
                  >
                    Formação
                  </a>
                </li>
                <li className="nav__li">
                  <a 
                    className="nav__a" 
                    href="#projetos" 
                    onClick={(e) => handleAnchorClick(e, 'projetos')}
                  >
                    Projetos
                  </a>
                </li>
                <li className="nav__li">
                  <a 
                    className="nav__a" 
                    href="#contato" 
                    onClick={(e) => handleAnchorClick(e, 'contato')}
                  >
                    Contato
                  </a>
                </li>
            </ul>
        </nav>
    );
}

export default Nav;

方法2:结合useNavigate实现锚点滚动

若想保留类似Link的交互逻辑,可使用useNavigate确保在首页路由后,再滚动到对应锚点:

// Nav.js 修改后的代码
import "../styles/nav/nav.css";
import "../styles/nav/nav-ul.css";
import "../styles/nav/nav-li.css";
import "../styles/nav/nav-a.css";
import "../styles/nav/nav-imagem.css";
import "../styles/nav/nav-button.css";
import Tracos from "../images/tracos.png";
import { useNavigate } from "react-router-dom";

function Nav(){
    const navigate = useNavigate();
    function showMenu(){
        let ul = document.querySelector(".nav__ul");
        if(ul.style.display===""){
            ul.style.display="flex";
        }else if(ul.style.display==="flex"){
            ul.style.display="";
        }
    }

    const handleAnchorClick = (targetId) => {
        // 先跳转到首页路由
        navigate('/');
        // 等待DOM更新后执行滚动
        setTimeout(() => {
            const element = document.getElementById(targetId);
            if(element){
                element.scrollIntoView({ behavior: 'smooth' });
            }
        }, 100);
    }

    return (
        <nav className="nav">
            <button className="nav__button" onClick={ () => showMenu() }>
                <img className="nav__imagem" src={ Tracos } alt="" />
            </button>
            <ul className="nav__ul">
                <li className="nav__li">
                  <span 
                    className="nav__a" 
                    onClick={() => handleAnchorClick('cabecalho')}
                  >
                    Início
                  </span>
                </li>
                <li className="nav__li">
                  <span 
                    className="nav__a" 
                    onClick={() => handleAnchorClick('quem-e')}
                  >
                    Quem é Priscila?
                  </span>
                </li>
                <li className="nav__li">
                  <span 
                    className="nav__a" 
                    onClick={() => handleAnchorClick('formacao')}
                  >
                    Formação
                  </span>
                </li>
                <li className="nav__li">
                  <span 
                    className="nav__a" 
                    onClick={() => handleAnchorClick('projetos')}
                  >
                    Projetos
                  </span>
                </li>
                <li className="nav__li">
                  <span 
                    className="nav__a" 
                    onClick={() => handleAnchorClick('contato')}
                  >
                    Contato
                  </span>
                </li>
            </ul>
        </nav>
    );
}

export default Nav;

补充:BrowserRouter在GitHub Pages白屏的原因

GitHub Pages是静态文件托管服务,不支持SPA前端路由的服务器端适配。使用BrowserRouter时,刷新页面或直接访问子路由(如/admin),服务器会因找不到对应物理文件返回404,导致白屏。HashRouter通过#管理路由,所有请求都会指向根文件,因此不会出现该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:32:02