You need to enable JavaScript to run this app. Next.js项目使用react-router-dom的Link报Router外部使用错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目使用react-router-dom的Link报Router外部使用错误如何解决

问题原因
  • 核心错误:你从react-router-dom导入了<Link>组件使用,但所有react-router-dom的路由组件都必须在<Router>上下文下运行,你导入了BrowserRouter as Router但全程没有使用该组件包裹子节点,导致Link找不到路由上下文抛出报错。
  • 次要问题:你在Navbar.js中存在命名冲突,同时从react-router-dom导入BrowserRouter as Router、从next/router导入Router,重名导入会互相覆盖失效。
  • 额外说明:Next.js本身自带基于pages目录的内置路由能力,不需要额外引入react-router-dom做路由管理,强行混用会导致服务端渲染阶段出现更多兼容问题。

解决方案

方案1:优先推荐,改用Next.js内置路由(无需react-router-dom)

步骤1:卸载冗余依赖

yarn remove react-router-dom
# 或使用npm
npm uninstall react-router-dom

步骤2:修改Navbar.js代码

替换react-router-dom的路由能力为Next.js原生API:

import { FaBars } from 'react-icons/fa';
import Link from 'next/link';
import { useRouter } from 'next/router';
import styled from 'styled-components';

export const Nav = styled.nav`
  background: #000;
  height: 80px;
  display: flex;
  justify-content: space-between;
  padding: 0.5rem calc((100vw - 1000px) / 2);
  z-index: 10;
`;

// 封装带激活状态的导航链接
const NavLinkWrapper = ({ href, children, activeStyle }) => {
  const router = useRouter();
  const isActive = router.pathname === href;
  return (
    <Link href={href} passHref>
      <a className={isActive ? 'active' : ''} style={isActive && activeStyle ? activeStyle : {}}>
        {children}
      </a>
    </Link>
  )
}

export const NavLink = styled(NavLinkWrapper)`
  color: #fff;
  display: flex;
  align-items: center;
  text-decoration: none;
  padding: 0 1rem;
  height: 100%;
  cursor: pointer;
  &.active {
    color: #15cdfc;
  }
`;

export const Bars = styled(FaBars)`
  display: none;
  color: #fff;
  @media screen and (max-width: 768px) {
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(-100%, 75%);
    font-size: 1.8rem;
    cursor: pointer;
  }
`;

export const NavMenu = styled.div`
  display: flex;
  align-items: center;
  margin-right: -24px;
  @media screen and (max-width: 768px) {
    display: none;
  }
`;

export const NavBtn = styled.nav`
  display: flex;
  align-items: center;
  margin-right: 24px;
  @media screen and (max-width: 768px) {
    display: none;
  }
`;

// 封装按钮链接
const NavBtnLinkWrapper = ({ href, children }) => {
  return (
    <Link href={href} passHref>
      <a>{children}</a>
    </Link>
  )
}

export const NavBtnLink = styled(NavBtnLinkWrapper)`
  border-radius: 4px;
  background: #256ce1;
  padding: 10px 22px;
  color: #fff;
  outline: none;
  border: none;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
  text-decoration: none;
  margin-left: 24px;
  &:hover {
    transition: all 0.2s ease-in-out;
    background: #fff;
    color: #010606;
  }
`;

function Navbar(props) {
    return (
            <>
                <Nav>
                    <NavLink href='/'>
                        <img alt='logo' />
                    </NavLink>
                    <Bars />
                    <NavMenu>
                        <NavLink href='/about' activeStyle>
                            About
                        </NavLink>
                        <NavLink href='/services' activeStyle>
                            Services
                        </NavLink>
                        <NavLink href='/contact-us' activeStyle>
                            Contact Us
                        </NavLink>
                        <NavLink href='/sign-up' activeStyle>
                            Sign Up
                        </NavLink>
                    </NavMenu>
                    <NavBtn>
                        <NavBtnLink href='/signin'>Sign In</NavBtnLink>
                    </NavBtn>
                </Nav>
            </>
    );
}

export default Navbar;

步骤3:创建对应路由页面

在pages目录下新建about.js、services.js、contact-us.js、sign-up.js、signin.js文件,Next.js会自动生成对应路由,无需额外配置。


方案2:仍要使用react-router-dom的临时修复方法

步骤1:修复命名冲突

删除Navbar.js中import {Router} from "next/router";这一行,避免重名覆盖。

步骤2:全局包裹Router上下文

新建/修改pages/_app.js文件,在最外层包裹路由容器:

import { BrowserRouter as Router } from 'react-router-dom';

function MyApp({ Component, pageProps }) {
  return (
    <Router>
      <Component {...pageProps} />
    </Router>
  )
}

export default MyApp

注意:该方案在Next.js服务端渲染场景下可能出现更多兼容问题,不推荐长期使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 23:54:03