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

react-router-dom跳转异常:地址栏变化但页面需刷新才能生效

地址栏变化但页面不跳转的React路由问题

我正在开发一个React项目,点击链接时地址栏会变化,但页面不会自动跳转,必须手动刷新才能看到对应页面。以下是我的代码:

App组件代码

import Hero from './components/Hero'
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import ContactPage from './components/ContactPage';
import Solar from './components/Solar';
import Navbar from './components/Navbar';
import Wind from './components/Wind';
import Mission from './components/Mission'
import Vision from './components/Vision'
import Projects from './components/Projects';

function App() {
  return (
    <BrowserRouter>
      <Navbar />
      <Switch>
        <Route exact path='/' component={Hero} />
        <Route path='/contact' component={ContactPage} />
        <Route path='/solar' component={Solar} />
        <Route path='/wind' component={Wind} />
        <Route path='/mission' component={Mission} />
        <Route path='/vision' component={Vision} />
        <Route path='/projects' component={Projects} />
      </Switch>
    </BrowserRouter>
  );
}

export default App;
import React, { useEffect, useState } from 'react'
import { AiOutlineMenu, AiOutlineClose, AiOutlineDown } from 'react-icons/ai'
import { motion } from 'framer-motion'
import { useOnHoverOutside } from '../hooks/useOnHoverOutside'
import { Link } from 'react-router-dom'

const Navbar = () => {
  const [nav, setNav] = useState(false)
  const [color, setColor] = useState('transparent')
  const [textColor, setTextColor] = useState('white')
  const [isAboutUsMenuDropdown, setIsAboutUsMenuDropDown] = useState(false)
  const [isProjectsMenuDropdown, setIsProjectsMenuDropDown] = useState(false)

  const handleNav = () => {
    setNav(!nav);
  }

  const closeHoverMenu = () => {
    setIsAboutUsMenuDropDown(false);
    setIsProjectsMenuDropDown(false)
  }

  useOnHoverOutside(closeHoverMenu) // Call the hook

  useEffect(() => {
    const changeColor = () => {
      if (window.scrollY >= 90) {
        setColor('#ffffff')
        setTextColor('#006400')
      } else {
        setColor('transparent')
        setTextColor('#ffffff')
      }
    }
    window.addEventListener('scroll', changeColor)
  }, [])

  return (
    <motion.nav
      animate={{ backgroundColor: `${color}` }}
      initial={{ backgroundColor: 'transparent' }}
      className='fixed left-0 top-0 w-full z-10 ease-in duration-300'
    >
      <div className='max-w-[1240px] m-auto flex justify-between items-center p-4 text-white'>
        <a to="/">
          <img src={require("../images/calogo.png")} className="w-20 h-20" alt="/" />
        </a>
        <ul
          style={{ color: `${textColor}` }}
          className='hidden sm:flex font-semibold'
        >
          <li className='p-4' onMouseOver={() => setIsAboutUsMenuDropDown(true)} onMouseOut={() => setIsAboutUsMenuDropDown(false)}>
            <a href='/' className='inline-flex'>About Us <AiOutlineDown className='ml-2 mt-1' /></a>
            {isAboutUsMenuDropdown && (
              <ul className="absolute z-10 bg-gray-600/60 text-white rounded py-2 mt-2" style={{ animation: "slideDown 0.3s ease-out forwards" }}>
                <li className="py-1">
                  <Link to="/mission" className="block px-4 py-1 text-white hover:bg-gray-500">
                    Mission
                  </Link>
                </li>
                <li className="py-1">
                  <Link to="/vision" className="block px-4 py-1 text-white hover:bg-gray-500">
                    Vision
                  </Link>
                </li>
              </ul>
            )}
          </li>
          <li className='p-4' onMouseOver={() => setIsProjectsMenuDropDown(true)} onMouseOut={() => setIsProjectsMenuDropDown(false)}>
            <Link to='/projects' className='inline-flex'>Projects <AiOutlineDown className='ml-2 mt-1' /></Link>
            {isProjectsMenuDropdown && (
              <ul className="absolute z-10 bg-gray-600/60 text-white rounded py-2 mt-2">
                <li className="py-1">
                  <Link to="/solar" className="block px-4 py-1 text-white hover:bg-gray-500">
                    Solar
                  </Link>
                </li>
                <li className="py-1">
                  <Link to="/wind" className="block px-4 py-1 text-white hover:bg-gray-500">
                    Wind
                  </Link>
                </li>
              </ul>
            )}
          </li>
          <li className='p-4'>
            <Link to='/contact'>Contact</Link>
          </li>
        </ul>

        {/* Mobile Button */}
        <div onClick={handleNav} className='block sm:hidden z-10'>
          {nav ? (
            <AiOutlineClose size={20} style={{ color: `${textColor}` }} />
          ) : (
            <AiOutlineMenu size={20} style={{ color: `${textColor}` }} />
          )}
        </div>
        {/* Mobile Menu */}
        <div className={nav
          ? 'sm:hidden absolute top-0 left-0 right-0 bottom-0 flex justify-center items-center w-full h-screen bg-black text-center ease-in duration-300'
          : 'sm:hidden absolute top-0 left-[-100%] right-0 bottom-0 flex justify-center items-center w-full h-screen bg-black text-center ease-in duration-300'}
        >
          <ul>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#aboutus'>About Us</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#mission'>Mission</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#vision'>Vision</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#projects'>Projects</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#solar'>Solar</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#wind'>Wind</a>
            </li>
            <li className='p-4 text-4xl hover:text-gray-500'>
              <a href='/#contact'>Contact</a>
            </li>
          </ul>
        </div>
      </div>
    </motion.nav>
  )
}

export default Navbar

问题原因及解决方案

问题出在混用了原生HTML的<a>标签和React Router的<Link>组件,原生<a>标签会触发浏览器默认跳转行为,导致页面路由异常(地址栏变化但组件不更新),而React Router需要用<Link>实现无刷新的客户端路由。

需要修改的几个地方:

  1. Logo链接:<a>标签不支持to属性,替换为<Link>组件:
<Link to="/">
  <img src={require("../images/calogo.png")} className="w-20 h-20" alt="logo" />
</Link>
  1. About Us主链接:将原生<a href='/'>替换为<Link to='/'>:
<Link to='/' className='inline-flex'>About Us <AiOutlineDown className='ml-2 mt-1' /></Link>
  1. 移动端菜单所有链接:全部替换为<Link>组件,同时去掉路径中的#(#是锚点链接,不是路由路径):
<ul>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/'>About Us</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/mission'>Mission</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/vision'>Vision</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/projects'>Projects</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/solar'>Solar</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/wind'>Wind</Link>
  </li>
  <li className='p-4 text-4xl hover:text-gray-500'>
    <Link to='/contact'>Contact</Link>
  </li>
</ul>
  1. 检查useOnHoverOutside钩子:确保该钩子没有错误拦截<Link>的点击事件,如果钩子绑定的元素包含<Link>,需调整目标元素范围,避免干扰路由跳转。

总结

将所有路由跳转链接替换为React Router的<Link>组件,即可解决地址栏变化但页面不更新的问题。<Link>会拦截浏览器默认跳转行为,通过React Router的客户端路由机制更新组件,无需手动刷新页面。

内容的提问来源于stack exchange,提问作者Egemen Özyürek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:09:27