Skip to content

路由信息

React Router v6 对路由信息的访问和使用进行了简化,并引入了一些新的特性,使得开发者可以更方便地管理路由逻辑。在 v6 中,一些 API 和 Hook 有所变化,但核心概念保持一致。以下是关于如何在 React Router v6 中访问和使用路由信息的详细介绍。

主要的路由信息对象

1. useNavigate

取代了 useHistoryuseNavigate 是一个 Hook,用于执行编程式的导航操作。它返回一个函数,你可以调用这个函数来改变 URL 或历史记录栈。

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

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

  return (
    <button onClick={() => navigate(-1)}>
      Go Back
    </button>
  );
}

2. useLocation

与之前的版本相同,useLocation Hook 返回当前的 location 对象,包含了路径名 (pathname)、查询参数 (search) 和哈希 (hash) 等信息。

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

function ShowLocation() {
  const location = useLocation();

  return <div>You are at {location.pathname}</div>;
}

3. useParams

这个 Hook 用于获取动态路径参数(如 /user/:id 中的 id)。它返回一个包含所有匹配参数的对象。

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

function UserProfile() {
  let { id } = useParams();
  return <h2>User Profile: {id}</h2>;
}

4. useMatch

这是一个新的 Hook,在 React Router v6 中用来替代 useRouteMatch。它可以接受一个路径模式作为参数,并返回一个匹配结果对象或 null 如果没有匹配。这对于嵌套路由或条件渲染非常有用。

jsx
import { useMatch } from 'react-router-dom';

function ShowMatch() {
  let match = useMatch('/users/:userId');
  if (match) {
    return <div>Matching user ID: {match.params.userId}</div>;
  }
  return <div>No match found</div>;
}

使用 <Routes><Route> 组件

React Router v6 引入了 <Routes> 组件,它会自动选择最匹配的路由进行渲染,而不再需要显式地使用 Switch 组件。此外,<Route> 组件现在使用 element 属性来指定要渲染的组件,而不是 componentrender 函数。

jsx
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './Home';
import About from './About';
import Contact from './Contact';
import User from './User';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="/user/:id" element={<User />} />
      </Routes>
    </Router>
  );
}

嵌套路由

React Router v6 支持嵌套路由,即一个路由可以包含其他路由。这使得构建复杂的应用结构变得非常容易。父级路由和子级路由之间的路径组合会形成完整的匹配路径。

jsx
<Route path="users" element={<UsersLayout />}>
  <Route index element={<AllUsers />} />
  <Route path=":userId" element={<UserProfile />} />
</Route>

导航链接

<Link><NavLink> 组件保持不变,仍然用于创建导航链接。<NavLink> 提供了一个 activeClassNamestyle 属性来设置激活状态下的样式。

jsx
import { Link, NavLink } from 'react-router-dom';

<nav>
  <ul>
    <li><Link to="/">Home</Link></li>
    <li><NavLink to="/about" className={({ isActive }) => isActive ? 'selected' : ''}>About</NavLink></li>
    <li><NavLink to="/contact" className={({ isActive }) => isActive ? 'selected' : ''}>Contact</NavLink></li>
  </ul>
</nav>

示例代码

以下是一个完整的例子,展示了如何结合上述信息来构建一个简单的单页应用,并展示当前的路由信息:

jsx
import React from 'react';
import { BrowserRouter as Router, Route, Routes, Link, useNavigate, useLocation, useParams, useMatch } from 'react-router-dom';

const Home = () => <h2>Home</h2>;
const About = () => <h2>About</h2>;
const Contact = () => <h2>Contact</h2>;

function UserProfile() {
  let { id } = useParams();
  return <h2>User Profile: {id}</h2>;
}

function RouteInfo() {
  let navigate = useNavigate();
  let location = useLocation();
  let params = useParams();
  let match = useMatch('/users/:userId');

  return (
    <div>
      <p>Location: {location.pathname}</p>
      <p>Params: {JSON.stringify(params)}</p>
      <p>User Match: {match ? `Matching user ID: ${match.params.userId}` : 'No match found'}</p>
      <button onClick={() => navigate('/')}>Go to Home</button>
    </div>
  );
}

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
            <li><Link to="/contact">Contact</Link></li>
            <li><Link to="/user/123">User 123</Link></li>
            <li><Link to="/info">Route Info</Link></li>
          </ul>
        </nav>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/contact" element={<Contact />} />
          <Route path="/user/:id" element={<UserProfile />} />
          <Route path="/info" element={<RouteInfo />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

总结

React Router v6 提供了一套强大且直观的 API 来处理单页应用中的路由管理。通过理解并正确使用这些路由信息相关的 Hooks 和组件,你可以轻松地实现复杂的导航逻辑、处理动态路径参数以及响应 URL 的变化。

Released under the MIT License.