首页 / 文章 / React Router基础:BrowserRouter、Routes,以及Route和Link详解

React Router基础:BrowserRouter、Routes,以及Route和Link详解

了解在 React Router 中 BrowserRouter、Routes、Route 和 Link 的各自功能,它们如何在同一个应用中协同工作,以及如何回答关于它们的常见面试问题。

930 词

大多数 React 应用很快就需要多个页面,比如首页、关于我们、产品介绍和联系我们。React 本身并不支持 URL 概念,因此将地址与页面对应的工作由相关库来完成,通常是 React Router。它包含四个核心组件,可覆盖大多数常见路由场景:<BrowserRouter><Routes><Route><Link>。一旦了解每个组件的功能及其嵌套方式,你就能构建多页面的单页应用,并在面试中清晰解释其原理。

BrowserRouter:连接 React 与 URL

<BrowserRouter> 就是路由器本身。它通过浏览器的 History API 实现客户端路由,使渲染的界面与地址栏保持同步,而无需向服务器请求新文档。

当您的应用需要为不同页面提供独立的URL,但整体仍表现为一个页面时,请使用此方法,例如:

/
/about
/products
/contact

设置方式就是将组件树包裹起来;所有需要路由处理的元素都必须位于该结构内部:

import { BrowserRouter } from "react-router-dom";
function App() {
  return (
    <BrowserRouter>
      {/* Application routes */}
    </BrowserRouter>
  );
}

通常只需在根节点处配置一次。一个实际后果是:由于像 /about 这样的路径属于真实URL,您的服务器必须为所有这些路径提供相同的 index.html,否则在访问 /about 时就会返回服务器404错误。

路由决定要渲染的内容

<Routes> 是用于存放路由定义的容器。每当页面地址发生变化时,它会将当前URL与其中的路由项进行比较,并渲染匹配的那一项。每当需要由React Router而非手动编写的条件判断来决定显示哪个页面时,请使用此方法:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="/products" element={<Products />} />
</Routes>

这里,一个 <Routes> 元素负责处理所有三条路径。它会选择最匹配的路径而非列表中的第一个,因此几乎无需担心顺序问题。

路由将一个路径映射到一个元素

每个 <Route> 都会将一个 URL 路径与要显示的组件对应起来,就像查找表中的一条记录:

/about → About component
/products → Products component

对于每个需要渲染特定内容的 URL,都需要添加一个对应的元素。关键的属性是 pathelement

<Route
  path="/about"
  element={<About />}
/>

根据这样的定义,访问该地址时:

/about

会促使 React Router 进行渲染:

<About />

请注意,element 接收的是已渲染的元素(如 <About />),而非组件引用,因此可以直接传递属性。多个路由的组合形式如下:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="/contact" element={<Contact />} />
</Routes>

如果没有匹配的路径,此块中的内容将不会显示;通常使用通用的 path="*" 路由来展示“未找到”页面。

无需重新加载即可跳转

可在应用保持加载状态的情况下将用户切换到不同路由。它在 DOM 中渲染一个普通的 标签,但会拦截点击事件并让 React Router 处理导航。可将其用于导航栏等内部跳转场景:

import { Link } from "react-router-dom";
function Navbar() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/contact">Contact</Link>
    </nav>
  );
}

点击 关于 会更新 URL, 会重新进行评估,这样无需刷新浏览器即可显示关于页面,从而保持共享的布局和内存中的状态。对于外部网站,使用普通的 标签仍然是正确的做法。

将四者结合使用

一个最简的完整配置(HomeAboutContact在其他地方定义):

import {
  BrowserRouter,
  Routes,
  Route,
  Link
} from "react-router-dom";
function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/contact">Contact</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

链接与<Routes>块都位于<BrowserRouter>内部,属于同级元素:导航会在每个页面上持续显示,只有<Routes>区域的内容会发生变化。其层级结构简述如下:

BrowserRouter
      ↓
    Routes
      ↓
    Route
      ↓
  Component

<Link>位于该链的旁边,是用户点击以更改URL的控制元素。这些示例来自react-router-dom;较新的大版本也提供了react-router包中的这些API,因此请查阅对应版本的文档。

面试问题

  • 什么是<BrowserRouter>它是一种实现客户端路由的路由器,能够使用户界面与浏览器URL保持同步。
  • <Routes><Route>有何区别?<Routes>是用于匹配URL的容器;每个<Route>定义一个路径以及要渲染的元素。
  • <Link><a>有何不同?<Link>可在客户端直接跳转而无需完全重新加载页面;而普通的<a>则会迫使浏览器再次加载该URL对应的页面。
  • 在React Router应用中为何推荐使用<Link>因为它能使应用保持单页应用的结构,避免不必要的整页重新加载。
  • <Route>能否在没有<BrowserRouter>的情况下使用?通常不能:路由组件必须要在如<BrowserRouter>这样的路由器上下文中进行渲染。
  • 核心要点

    • <BrowserRouter>用于在根层级实现一次路由配置。
    • <Routes>负责管理路由并渲染匹配的页面。
    • <Route>将URL映射到对应的组件。
    • <Link>可在不重新加载页面的情况下在路由之间切换。

    嵌套路由、动态路径段、受保护的路由以及导航钩子都基于这一相同模型构建。关于React在路由变化时如何决定重新渲染的内容,可参阅React重新渲染、状态与钩子的思维模型构建

    相关阅读