当前位置:首页 > 技术 > 正文内容

React Router DOM v6与v5版本核心差异与用法详解

访客 技术 2026年6月9日 1

React Router DOM v6的发布标志着React路由管理的一次重要演进。相较于v5版本,v6在API设计、功能实现和开发体验上都有显著变化,尤其是在函数式组件和Hooks日益普及的背景下,v6的许多改动都围绕着更简洁、更现代的开发模式展开。本文将深入对比v5与v6的核心差异,并重点介绍v6的实际应用。

React Router DOM v6的主要变更

  • <Switch> 升级为 <Routes>: <Routes> 提供了更优化的路由匹配逻辑。
  • 路由组件渲染方式变更: 使用 element prop 替代了 v5 中的 component prop 来渲染路由匹配到的组件。
  • 相对路径自动解析: 子路由的 path 属性现在可以省略父路由的路径前缀,React Router 会自动处理。
  • useNavigate 替代 useHistory: 提供了更简洁的编程式导航API。
  • <Navigate> 替代 <Redirect>: 用于实现路由重定向,功能更强大。
  • 优化的路由嵌套与 <Outlet>: <Outlet> 组件作为子路由的渲染出口,类似于Vue Router中的 <router-view>
  • index 路由: 用于定义嵌套路由中的默认路由。
  • 新增 useResolvedPath Hook: 用于解析URL路径。
  • 新增 useSearchParams Hook: 简化了URL查询参数的读写操作。
  • <Link> 支持相对路径语法: to 属性支持 ...,便于在嵌套路由中导航。
  • path 通配符限制: 仅支持 *:,移除了如 ? 等更复杂的通配符。
  • 新增 useOutletContext Hook: 便于在嵌套路由之间共享状态。

React Router DOM v6 基础用法

安装


npm install --save react-router-dom@6.x
    

全局配置

在项目的入口文件(通常是 index.jsmain.jsx)中,使用 BrowserRouterHashRouter 包裹整个应用:


import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
    

BrowserRouter vs HashRouter:

  • BrowserRouter: 基于 HTML5 History API,URL 不带 #。在刷新页面时,如果路由 state 参数存在,BrowserRouter 能更好地维持状态,因为它依赖于浏览器历史记录。
  • HashRouter: 基于 URL 的 hash 值(#),URL 带 #。在刷新页面时,hash 值相关的路由 state 可能会丢失。

路由定义方式

1. 直接在组件中定义路由


import { NavLink, Routes, Route, Navigate } from 'react-router-dom';
import About from './components/About.jsx';
import Home from './components/Home.jsx';
import Children from "./components/Children.jsx";

function App() {
  return (
    <div>
      <nav>
        <NavLink to="/home">Home</NavLink>
        <NavLink to="/about">About</NavLink>
      </nav>
      <div className="content">
        <Routes>
          <Route path="/home" element={<Home />}>
             {/* 嵌套路由 */}
             <Route path="children" element={<Children />} />
          </Route>
          <Route path="/about" element={<About />} />
          {/* 根路径重定向到 /home */}
          <Route path="/" element={<Navigate to="/home" replace />} />
        </Routes>
      </div>
    </div>
  );
}

export default App;
    

<Navigate>: 当此组件被渲染时,它会改变当前 URL,实现视图切换,常用于路由重定向和设置默认加载的页面。

2. 使用路由表


// src/routes/index.js
import { Navigate } from 'react-router-dom';
import About from '../components/About.jsx';
import Home from '../components/Home.jsx';
import Children from "../components/Children.jsx";

const routeConfig = [
  // 路由重定向
  {
    path: '/',
    element: <Navigate to="/home" replace />,
  },
  {
    path: '/home',
    element: <Home />,
    children: [ // 子路由配置
      {
        path: "children", // 相对路径
        element: <Children />,
      },
    ],
  },
  {
    path: '/about',
    element: <About />,
  },
];

export default routeConfig;
    

App.jsx 中使用 useRoutes 挂载路由表:


// App.jsx
import { NavLink, useRoutes } from 'react-router-dom';
import routeConfig from './router'; // 引入路由表

function App() {
  const element = useRoutes(routeConfig); // 生成路由规则

  return (
    <div>
      <nav>
        <NavLink to="/home">Home</NavLink>
        <NavLink to="/about">About</NavLink>
      </nav>
      <div className="content">
        {element} {/* 在此渲染匹配的路由组件 */}
      </div>
    </div>
  );
}

export default App;
    

嵌套路由与 <Outlet>

<Outlet> 组件用于在父路由组件中指定子路由的渲染位置。


// src/components/Home.jsx
import React from 'react';
import { NavLink, Outlet } from 'react-router-dom';

function Home() {
  return (
    <div>
      <h2>Home Page</h2>
      <nav>
        <NavLink to="children">Go to Children</NavLink>
      </nav>
      <!-- 子路由渲染出口 -->
      <Outlet />
    </div>
  );
}

export default Home;
    

路由传参

1. Path Parameters (路径参数)

注册路由:path 中使用 :参数名


// 路由配置示例
{
  path: '/about/:userId',
  element: <About />,
}
    

传递参数: 使用 <NavLink>to 属性或 navigate 函数。


// 使用 NavLink
<NavLink to={`/about/${someUserId}`}>User Profile</NavLink>
    

接收参数: 使用 useParams Hook。


import { useParams } from 'react-router-dom';

function About() {
  const { userId } = useParams(); // 获取 userId 参数
  return <div>User Profile for ID: {userId}</div>;
}
    

2. Query Parameters (查询参数/Search参数)

注册路由: 无需特殊声明,直接匹配路径。


// 路由配置示例
{
  path: '/items',
  element: <Items />,
}
    

传递参数:to 属性后附加 ?参数名=值&参数名=值


// 使用 NavLink
const itemId = 123;
const category = 'electronics';
<NavLink to={`/items?id=${itemId}&category=${category}`}>View Item</NavLink>
    

接收参数: 使用 useSearchParams Hook。


import { useSearchParams } from 'react-router-dom';

function Items() {
  const [searchParams, setSearchParams] = useSearchParams();
  const id = searchParams.get('id');
  const category = searchParams.get('category');

  const updateParams = () => {
    setSearchParams({ id: '456', category: 'books' }); // 更新查询参数
  };

  return (
    <div>
      Item ID: {id}, Category: {category}
      <button onClick={updateParams}>Update Params</button>
    </div>
  );
}
    

3. State Parameters (状态参数)

注册路由: 无需特殊声明。


// 路由配置示例
{
  path: '/details',
  element: <Details />,
}
    

传递参数: 使用 <NavLink>navigate 函数的 state 属性。


// 使用 NavLink
const dataToSend = { itemId: 789, description: 'Sample Item' };
<NavLink to="/details" state={dataToSend}>View Details</NavLink>
    

接收参数: 使用 useLocation Hook 访问 location.state


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

function Details() {
  const location = useLocation();
  // 注意: location.state 可能为 null 或 undefined
  const { itemId, description } = location.state || {};

  return (
    <div>
      Item ID: {itemId}, Description: {description}
    </div>
  );
}
    

路由跳转

1. 使用 <NavLink>

通过 to 属性进行声明式导航。


<NavLink to="/home">Go to Home</NavLink>
    

2. 使用 useNavigate Hook

提供编程式导航能力。


import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const navigate = useNavigate();

  const goToChildren = () => {
    // 导航到 /home/children,并传递 state
    navigate('/home/children', {
      replace: false, // 是否替换当前历史记录
      state: { someData: 'example' },
    });
  };

  const goBack = () => {
    navigate(-1); // 后退一步
  };

  const goForward = () => {
    navigate(1); // 前进一步
  };

  return (
    <div>
      <button onClick={goToChildren}>Go to Children with State</button>
      <button onClick={goBack}>Back</button>
      <button onClick={goForward}>Forward</button>
    </div>
  );
}
    

useNavigate 返回一个函数,可以直接调用该函数进行导航。除了直接传递路径,还可以传递一个表示前进/后退步数的数字。

标签: react

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。