React Router DOM 完全指南 – wiki大全

React Router DOM 完全指南

引言

在构建单页应用程序 (SPA) 时,客户端路由是不可或缺的一部分。它允许用户在不重新加载整个页面的情况下,在应用程序的不同视图之间进行导航,从而提供流畅的用户体验。React Router DOM 是 React 社区中最流行且功能强大的路由库,它使得在 React 应用中实现声明式路由变得轻而易举。

本指南将带你深入了解 React Router DOM 的核心概念、基本用法和高级特性,帮助你构建出功能完善且易于维护的 React 应用程序。

核心概念

在使用 React Router DOM 之前,了解其几个核心组件和 Hooks 至关重要。

  1. BrowserRouter: 这是所有路由组件的顶层容器。它使用 HTML5 历史 API (pushState, replaceState 和 popstate 事件) 来保持 UI 与 URL 的同步。通常,你会将它包裹在你的根组件外面。
  2. Routes: 这是一个新的组件 (v6 版本引入),它取代了 Switch。它会遍历其所有的 Route 子元素,并只渲染第一个与当前 URL 匹配的 Route
  3. Route: 用于将 URL 路径与组件进行匹配。它接收 path (要匹配的 URL 路径) 和 element (当路径匹配时渲染的 React 元素) 属性。
  4. Link: 用于在应用程序内部进行导航。它渲染成一个 <a> 标签,但会阻止浏览器重新加载页面,而是通过 React Router DOM 进行客户端导航。
  5. NavLink: 类似于 Link,但它会根据当前 URL 是否匹配其 to 属性,自动添加 active 类或应用自定义样式,非常适合导航菜单。
  6. useNavigate Hook: (v6 版本引入) 允许你在组件中以编程方式进行导航,例如在表单提交后重定向用户。
  7. useParams Hook: 用于访问当前路由的动态参数 (例如 /users/:id 中的 id)。
  8. useLocation Hook: 返回一个 location 对象,其中包含当前 URL 的信息,如路径名、查询参数等。
  9. useSearchParams Hook: (v6 版本引入) 用于读取和修改 URL 的查询字符串参数。
  10. Outlet: (v6 版本引入) 在嵌套路由中,Outlet 组件会渲染其父路由中匹配的子路由元素。

基本用法

1. 安装 React Router DOM

首先,你需要在你的 React 项目中安装 react-router-dom

“`bash
npm install react-router-dom

或者

yarn add react-router-dom
“`

2. 设置 BrowserRouter

在你的 src/index.js (或你的应用入口文件) 中,用 BrowserRouter 包裹你的根组件 App

“`javascript
// src/index.js
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import ‘./index.css’;
import App from ‘./App’;
import { BrowserRouter } from ‘react-router-dom’;

const root = ReactDOM.createRoot(document.getElementById(‘root’));
root.render(





);
“`

3. 定义路由 (RoutesRoute)

在你的 src/App.js 或你希望定义路由的地方,使用 RoutesRoute 来声明你的应用程序路径和对应的组件:

“`javascript
// src/App.js
import React from ‘react’;
import { Routes, Route } from ‘react-router-dom’;
import Home from ‘./components/Home’;
import About from ‘./components/About’;
import Contact from ‘./components/Contact’;

function App() {
return (


} />
} />
} />

);
}

export default App;
“`

4. 导航 (LinkNavLink)

为了在页面之间导航,你需要使用 LinkNavLink 组件:

“`javascript
// src/App.js (导航示例)
import React from ‘react’;
import { Routes, Route, Link, NavLink } from ‘react-router-dom’;
import Home from ‘./components/Home’;
import About from ‘./components/About’;
import Contact from ‘./components/Contact’;

function App() {
return (

  <hr />

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

);
}

export default App;

// src/index.css (NavLink 的 active-link 样式)
/ nav li a.active-link {
background-color: #007bff;
color: white;
}
/
“`

高级特性

1. 路由参数 (useParams)

当你的路由需要根据 URL 中的动态部分来显示内容时 (例如用户详情页 /user/123),你可以使用路由参数。

“`javascript
// src/components/User.js
import React from ‘react’;
import { useParams } from ‘react-router-dom’;

function User() {
const { id } = useParams(); // 获取 URL 中的 :id 参数

return (

用户详情页

用户 ID: {id}

);
}

export default User;

// src/App.js 中的路由定义
// } />
“`

2. 嵌套路由 (Outlet)

嵌套路由允许你构建具有分层结构的 UI。父路由组件会渲染其自身的 UI,并在 Outlet 组件的位置渲染匹配到的子路由组件。

“`javascript
// src/components/Users.js (父组件,包含嵌套路由)
import React from ‘react’;
import { Routes, Route, Link, Outlet } from ‘react-router-dom’;

function UserList() {
return (

用户列表

  • 用户 1
  • 用户 2

);
}

function UserDetailNested() {
// 这里可以再次使用 useParams 获取嵌套路由中的 ID
return (

嵌套用户详情

这是嵌套路由中的用户详情页面。

);
}

function Users() {
return (

用户页面

  {/* Outlet 会渲染匹配到的子路由 */}
  <Outlet />

  {/* 可以在这里定义嵌套的 Routes,但更推荐在父 Routes 中定义 */}
  {/* 
    <Routes>
      <Route path="/" element={<UserList />} />
      <Route path=":id" element={<UserDetailNested />} />
      <Route path="new" element={<h3>创建新用户表单</h3>} />
    </Routes>
  */}
</div>

);
}

export default Users;

// src/App.js 中的路由定义 (注意 “/” 用于匹配所有子路径)
// }>
// } /> {/
/users /}
// } /> {/
/users/1, /users/2 /}
// 创建新用户表单\

} /> {/ /users/new */}
//

// 注意:在 React Router v6 中,嵌套的 通常直接定义在父 的 element prop 内部,或者像上面 组件中那样,使用 和独立的 块。
// 示例:
// }>
// } /> // index 路由匹配父路径
// } />
// 创建新用户表单\

} />
//
“`

3. 编程导航 (useNavigate)

useNavigate Hook 返回一个函数,可以用于在组件内部触发导航,无需用户点击 Link

“`javascript
// src/components/Login.js (示例:登录后跳转)
import React from ‘react’;
import { useNavigate } from ‘react-router-dom’;

function Login({ onLogin }) {
const navigate = useNavigate();

const handleLoginClick = () => {
onLogin(); // 模拟登录成功
navigate(‘/dashboard’); // 登录后跳转到仪表盘
};

return (

登录页面

);
}

export default Login;
“`

4. 重定向 (Navigate)

Navigate 组件允许你在组件渲染时立即触发重定向。

“`javascript
// src/App.js (示例:旧路径重定向到新路径)
import { Navigate } from ‘react-router-dom’;

// …

{/ … 其他路由 … /}
} /> {/ 重定向到 /about /}

// …
``replace` 属性会替换历史堆栈中的当前条目,而不是添加新条目。

5. 404 Not Found 路由

使用 path="*" 可以匹配任何未被前面路由匹配到的路径,通常用于显示 404 页面。

“`javascript
// src/components/NotFound.js
import React from ‘react’;

function NotFound() {
return (

404 – 页面未找到

抱歉,您访问的页面不存在。

);
}

export default NotFound;

// src/App.js 中的路由定义 (放在 Routes 的最后)
// } />
“`

6. 保护路由

保护路由 (或私有路由) 确保只有经过身份验证的用户才能访问特定页面。这通常通过创建一个包装组件来实现。

“`javascript
// src/components/Protected.js
import React from ‘react’;
import { Navigate } from ‘react-router-dom’;

function Protected({ isAuthenticated, children }) {
if (!isAuthenticated) {
// 如果未认证,重定向到登录页
return ;
}
return children; // 如果认证通过,渲染子组件
}

export default Protected;

// src/App.js 中的使用
//
// \
// \
// }
// />
“`

7. 查询参数 (useSearchParams)

查询参数是 URL 中 ? 后面跟着的键值对 (例如 /search?query=react&page=1)。useSearchParams Hook 允许你轻松地读取和修改它们。

“`javascript
// src/components/QueryParams.js
import React from ‘react’;
import { useSearchParams } from ‘react-router-dom’;

function QueryParams() {
const [searchParams, setSearchParams] = useSearchParams();

const name = searchParams.get(‘name’);
const age = searchParams.get(‘age’);

const handleUpdateParams = () => {
// 设置新的查询参数,这会更新 URL
setSearchParams({ city: ‘NewYork’, country: ‘USA’ });
};

return (

查询参数示例

URL 中的名字: {name || ‘N/A’}

URL 中的年龄: {age || ‘N/A’}

当前 URL 查询字符串: {searchParams.toString()}

);
}

export default QueryParams;

// src/App.js 中的路由定义
// } />
“`

结论

React Router DOM 是 React 应用程序中管理路由的强大工具。通过理解 BrowserRouterRoutesRouteLinkNavLink 等核心组件,以及 useNavigateuseParamsuseSearchParams 等 Hooks,你可以构建出具有良好用户体验和复杂导航逻辑的单页应用程序。

熟练掌握这些概念和实践,将使你能够更好地组织代码、提高应用性能,并为用户提供无缝的导航体验。希望这篇完全指南能帮助你更好地利用 React Router DOM 构建出色的 React 应用。


注意: 上述代码示例是基于 React Router DOM v6 版本。如果你使用的是旧版本,某些 API 可能有所不同。

滚动至顶部