React Router Dom 中的三种路由及其使用场景

1,300 阅读4分钟

React Router 是一个用于 React 应用程序的声明式路由库,它允许用户在不同的视图和组件之间导航,同时保持应用程序的单页特性。react-router-dom 提供了多种 Router 组件,每种都有其特定的用途和场景。以下是 BrowserRouterHashRouterMemoryRouter 的详细说明以及它们的使用场景。

1. BrowserRouter

BrowserRouter 是最常用的路由方式,它使用 HTML5 的 history.pushState API 来实现路由,不需要后端配置即可实现 URL 变化而页面不刷新的效果。

特点:

  • 使用 history.pushState API。
  • URL 看起来更干净,没有 #
  • 需要服务器端配置以支持客户端路由。

使用场景:

  • 当你的应用部署在服务器上,并且你可以通过服务器配置来支持 HTML5 History 模式时。

示例代码:

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

const App = () => (
  <Router>
    <div>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
      </ul>
      <hr />
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </div>
  </Router>
);

2. HashRouter

HashRouter 是一种备选的路由方式,它使用 URL 的 hash 部分(即 URL 中 # 后面的部分)来实现路由。这种方式不依赖于服务器端的配置,因为 hash 的变化不会触发服务器请求。

特点:

  • 使用 URL 的 hash 部分。
  • URL 中包含 #
  • 无需服务器端配置。

使用场景:

  • 当你无法控制服务器配置,或者在一个静态站点上实现路由时。

示例代码:

import { HashRouter as Router, Route, Link } from 'react-router-dom';

const App = () => (
  <Router>
    <div>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
      </ul>
      <hr />
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </div>
  </Router>
);

3. MemoryRouter

MemoryRouter 是一个特殊的路由,它将整个路由状态保存在内存中,而不是浏览器的 history 中。这意味着使用 MemoryRouter 时,路由变化不会显示在 URL 中。

特点:

  • 路由状态保存在内存中。
  • URL 不会变化。
  • 适用于不需要显示路由状态的场景。

使用场景:

  • 当你想要内部导航,而不改变浏览器的 URL 时。
  • 在某些特定的测试或非浏览器环境中。

示例代码:

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

const App = () => (
  <MemoryRouter initialEntries={['/']} initialIndex={0}>
    {/* ... 其他路由组件 */}
  </MemoryRouter>
);

在这个例子中,MemoryRouter 接收 initialEntriesinitialIndex 属性,分别用于设置初始路由和索引。


可能大家平时用 BrowserRouterHashRouter 比较多,而使用 MemoryRouter 的场景相对较少,但这并不意味着 MemoryRouter 没有它的用武之地。MemoryRouter 可以包裹你的组件树,提供路由上下文而不会与浏览器的 history 交互。这在测试或非浏览器环境中特别有用。下面展示 MemoryRouter 的详细用法:

import { MemoryRouter } from 'react-router-dom';
import { Route, Link } from 'react-router-dom';
import Home from './Home';
import About from './About';

const App = () => (
  <MemoryRouter initialEntries={['/home']}>
    <div>
      <nav>
        <Link to="/home">Home</Link> | 
        <Link to="/about">About</Link>
      </nav>

      <hr />

      <Route exact path="/home" component={Home} />
      <Route path="/about" component={About} />
    </div>
  </MemoryRouter>
);

在这个例子中:

  • MemoryRouter 包裹了整个应用,提供了路由的内存上下文。
  • initialEntries 属性设置了默认的路由路径,当 MemoryRouter 被渲染时,它将导航到这个路径。
  • Link 组件用于在不同的路由之间导航,点击它们会改变 MemoryRouter 的内部路由状态,但不会影响浏览器的地址栏。
  • Route 组件定义了不同的视图,根据当前的路由状态渲染对应的组件。

MemoryRouter 的用途

MemoryRouter 的关键特点在于它不依赖于浏览器的 history API,因此它不会影响浏览器的地址栏,也不会留下浏览器的历史记录。这使得 MemoryRouter 在以下场景中非常有用:

  1. 单元测试:在测试路由行为时,MemoryRouter 可以提供一致的路由上下文,而不需要模拟浏览器的 history API。
  2. 服务器端渲染:在服务器端渲染应用时,使用 MemoryRouter 可以避免与浏览器的 history API 交互,因为服务器环境没有浏览器对象。
  3. 独立组件:如果你有一个组件需要内部维护自己的路由逻辑,而这个逻辑不应该影响全局路由状态,你可以在这个组件内部使用 MemoryRouter

总的来说,MemoryRouter 提供了一个独立于浏览器环境的路由解决方案,它非常适合那些不需要浏览器 history 交互的场景。

结论

选择哪种路由组件取决于你的应用程序的需求和部署环境。BrowserRouter 是最推荐的方式,因为它提供了最佳的用户体验,但需要服务器端的支持。如果你无法控制服务器配置,或者在一个静态站点上工作,HashRouter 是一个不错的选择。而 MemoryRouter 则适用于那些不需要 URL 变化的内部导航场景。