React07-路由管理器react-router-dom(v6)

本文介绍了ReactRouter-dom的基本概念、安装步骤,以及如何进行基本路由配置、路由跳转、动态路由、查询参数、嵌套路由、多组路由和布局路由的使用。通过实例展示了如何在React项目中有效地管理页面视图和导航。
摘要由CSDN通过智能技术生成

react-router 是一个流行的用于 React 应用程序路由的库。它使我们能够轻松定义应用程序的路由,并将它们映射到特定的组件,这样可以很容易地创建复杂的单页面应用,并管理应用程序的不同视图。

react-router 是基于 React 构建的,因此与其他 React 库和工具集成得很好。它在许多 React 应用程序中广泛使用,并被认为是 React 中最佳实践的路由。

一、react-router-dom安装和简介

1. react-router-dom安装

使用 npm 或 yarn 安装 react-router-dom。

npm install --save react-router-dom

yarn add react-router-dom

2. react-router-dom 简介

react-router-dom 是 react-router 的一种实现方案,主要应用于网页端应用,它提供了一些常用的组件进行路由管理。

(1) Router 类组件

  • BrowserRouter:history 模式下的路由。
  • HashRouter:hash 模式下的路由。

(2) Route 组件

Route 是一个路由配置组件。

(3) Link 组件

Link 类似于 a 标签,可以用于路由跳转。

(4) useNavigate Hook

useNavigate 是一个钩子函数,可以用于路由跳转。

二、react-router-dom 基本使用

1. 引入 react-router-dom

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

这里的 BrowserRouter as Router 相当于给 BrowserRouter 起了一个别名叫 Router。Routes 组件用于包裹 Route 组件,Route 组件的父组件必须是 Routes。

2. 简单使用

使用 BrowserRouter 组件包裹 Routes 组件,再用 Routes 组件包裹 Route 组件,在 Route 组件中定义路由信息,就实现了一个简单的 react-router 场景。

Route 组件有 path 和 element 两个属性,path 属性代表路由路径,element 属性代表要渲染的组件。

index.js

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

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

app.js

import './App.css';
import { Routes, Route} from "react-router-dom";
import Home from "./views/Home";
import About from "./views/About";
import Error from "./views/Error";

function App() {
  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Home/>}/>
        <Route path="/about" element={<About/>}/>
        <Route path="*" element={<Error/>}/>
      </Routes>
    </div>
  );
}

export default App;

在上面的案例中,我们定义了一个根路由,指向 Home 页面。还定义一个指定路径路由 /about,指向 About 页面,表示当我们在浏览器地址栏中的页面地址后加上 /about 时,会跳转到 About 页面。

又定义了一个通用路由,指向 Error 页面,path="*" 表示如果浏览器地址栏中的页面地址不是以上定义的2种路由(即其他路由地址)时,就会跳转到 Error 页面。

注意:BrowserRouter 组件最好放在最顶层所有组件之外,这样能确保内部组件使用 Link 做路由跳转时不出错。

3. 路由跳转

跳转路由时,如果路由路径是 / 开头的是绝对路由,否则是相对路由,即相对于当前 URL进行改变。

(1) Link 组件

Link 组件只能在 Router 组件的内部使用,to 属性代表要跳转的路由地址。

import { Link } from "react-router-dom";
<Link to="/about">To About</Link>

(2) NavLink 组件

NavLink 组件和 Link 组件的功能是一致的,区别在于 NavLink 组件可以判断其 to 属性是否是当前匹配到的路由。
NavLink组件的 style 属性或 className 属性可以接收一个函数,函数接收一个含有 isActive 字段的对象为参数,可根据该参数调整样式。

import { Link } from "react-router-dom";
<NavLink to="/about" style={({ isActive }) => ( {color: isActive ? "red" : "black"} )}>To About</NavLink>

(3) useNavigate Hook

使用 useNavigate 钩子函数,可以在 js 代码中实现路由跳转。

useNavigate 必须在 Route 的上下文中使用,即必须包裹在 Router 标签内。

import { useNavigate } from "react-router-dom";
<button onClick={() => navigate("/about")}>To About</button>

4. 路由参数

(1) 路径参数(动态路由匹配)

在 Routes 组件内定义路由。对于动态路由,使用冒号(:)来指定动态部分。例如,要定义一个动态用户路由,可以:

App.js

<Routes>
  <Route path="/user/:userId" element={<User />} />
</Routes>

这里的 :userId 是动态部分,可以匹配任何放在 /user/ 后面的路径,比如 /user/123。

在路由的目标组件中,可以使用 useParams 钩子来访问动态参数。例如,在 User 组件中,可以这样获取 userId:

User.js

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

function User {
  let { userId } = useParams();
  console.log(userId); // 123
  // 使用 userId 作为你的逻辑的一部分
}

export default User;

上述案例中,访问 /user/123 能正确获取到 userId 为123。

(2) 查询参数

查询参数不需要在路由中定义,可以使用 useSearchParams 钩子函数来处理路径中的查询参数。

查询参数位于 URL 中,用于提供额外信息以便服务器能够更具体地处理请求。它们通常出现在网页地址(URL)的末尾,并且遵循一定的格式。

在 URL 中,查询参数是通过问号(?)与网址的其它部分分隔开的,并且可以包含一个或多个键值对。每个键值对都由一个键(key)和一个值(value)组成,用等号(=)连接。如果有多个查询参数,它们之间通常用符号与(&)分隔。

例如,在 URL https://example.com/page?param1=value1&param2=value2 中, param1=value1 和 param2=value2 是查询参数,它们提供了额外的信息给服务器。

useSearchParams Hook 返回当前组件获取到的查询参数对象及修改这个对象的方法,使用方法和 useState Hook 类似。

在使用 setSearchParams 方法时,必须传入所有查询参数,否则会覆盖已有查询参数。

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

function User() {
  // 使用 useSearchParams 钩子
  const [searchParams, setSearchParams] = useSearchParams();

  // 获取查询参数
  const userId = searchParams.get('userId');

  // 设置查询参数
  const setUserId = (newUserId) => {
    setSearchParams({ userId: newUserId });
  };

  // 渲染组件
  return (
    <div>
      <p>当前的 userId 是:{userId}</p>
      <button onClick={() => setUserId('123')}>设置 userId 为 123</button>
    </div>
  );
}

export default User;

上述案例中,访问 /user?userId=123456 时,效果如下:

点击按钮后,userId 变为 123,符合预期。

(3) 状态参数

react-router 对 window.location 进行了包装,状态参数就位于包装后的 location 对象的 state 属性中。下面为包装后的 location 对象的属性:

react-router包装后的location对象
pathname主机名之后的 URL 地址
search查询参数
hash哈希值,用于确定页面滚动的具体位置
state对于 window.history.state 的包装
key每个 location 对象拥有一个唯一的 key

state 不显示在页面上,不会引起页面刷新,可用于记录用户的跳转详情或在跳转时携带信息,可以用在 Link 组件或 navigate 方法中使用状态参数。

{/* Link 中使用状态参数 */}
<Link to="/about" state={{ id: 123 }} >To About</Link>

{/* useNavigate 中使用状态参数 */}
<button onClick={() => navigate("/about", { state: { id: 456 } })}>To About</button>

在目标组件中,使用 useLocation 来获取封装后的 loaction 对象,进而获取状态参数。

const location = useLocation();
console.log(location.state);

5. 路由重定向

当在某个路径 /a ,要重定向到路径 /b 时,可以通过 Navigate 组件进行重定向到其他路径。

import { Navigate } from “react-router-dom”;

function A() {
  return <Navigate to=”/b" />;
}

export default A;

三、react-router-dom 进阶使用

1. 嵌套路由

嵌套路由是前端开发中用于组织和管理路由的一种技术,特别适用于构建具有层次结构的页面和应用程序。

在 Route 组件内定义 Route 组件实现嵌套路由,在父组件中使用 Outlet 组件作为子组件的占位符(显示匹配到的子组件)。

在嵌套路由中,如果 URL 仅匹配了父级 URL,则 Outlet 组件中会显示带有 index 属性的子路由,这个子路由称为默认路由。

例3-1:根据用户 id 显示用户详细信息

App.js

import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Home from './views/Home';
import Users from './views/Users';
import UserList from "./views/UserList";
import UserDetail from "./views/UserDetail";

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/users">User</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="users" element={<Users />}>
          <Route index element={<UserList />} />
          <Route path=":userId" element={<UserDetail />} />
        </Route>
      </Routes>
    </Router>
  );
}

export default App;

Users.js

import { Link, Outlet } from "react-router-dom";

function Users() {
  return (
    <div>
      <h2>Users</h2>
      <nav>
        <Link to="list">User List</Link>
      </nav>
      <Outlet />
    </div>
  );
}

export default Users;

UserList.js

import { Link } from "react-router-dom";

function UserList() {
  const users = [
    {id: "1", name: 'John'},
    {id: "2", name: 'Jane'},
    {id: "3", name: 'Mary'},
  ];
  return (
    <div>
      <h2>User List</h2>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <Link to={`/users/${user.id}`}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;

UserDetail.js

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

function UserDetail() {
  const { userId } = useParams();
  const users = [
    {id: "1", name: 'John'},
    {id: "2", name: 'Jane'},
    {id: "3", name: 'Mary'},
  ];
  return (
    <div>
      <h3>User Detail</h3>
      <h3>id:{userId}</h3>
      <h3>name:{users.find((user) => user.id === userId).name}</h3>
    </div>
  )
}

export default UserDetail;

上述案例中,在根组件 App 中定义了一组嵌套路由,一级路由为 / 和 users。又在 users 中嵌套了默认路由和动态路由 :userid。

在这个嵌套路由中,Users 组件为父组件,UserList 和 UserDetail 组件为子组件。在 Users 组件中使用了 Outlet 组件,作为匹配到的子组件的占位符。可以使用在路由的任何层级。当访问 /users 时,这里触发默认路由显示 UserList 组件。当访问 /users/2 时,会显示 UserDetail 组件。

访问 /users:

访问 /users/2:

2. 多组路由

多组路由指的是在单个应用中设置多个独立的路由组,可以在不同部分的应用中实现独立的路由逻辑,增加了路由结构的灵活性和模块化。

在 react-router-dom 中,可以通过在不同的组件中定义多个 Routes 组件来实现多组路由。

例3-2 管理系统案例

App.js

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import MainSite from './views/MainSite';
import AdminPanel from './views/AdminPanel';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="*" element={<MainSite />} />
        <Route path="admin/*" element={<AdminPanel />} />
      </Routes>
    </Router>
  );
}

export default App;

MainSite.js

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

function MainSite() {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
}

export default MainSite;

AdminPanel.js

import { Routes, Route, Link } from 'react-router-dom';
import Dashboard from './Dashboard';
import Users from './Users';

function AdminPanel() {
  return (
    <div>
      <nav>
        <Link to="/admin/dashboard">Dashboard</Link> |
        <Link to="/admin/users">Users</Link>
      </nav>
      <Routes>
        <Route path="dashboard" element={<Dashboard />} />
        <Route path="users" element={<Users />} />
      </Routes>
    </div>
  );
}

export default AdminPanel;

上述案例构建了一个具有两个独立路由组的应用,这两个路由组分别是主站(MainSite 组件)和管理面板(AdminPanel 组件)。MainSite 组件包含了应用的主要页面,如首页(Home)和关于页面(About);AdminPanel 组件是应用的管理面板,包含了仪表盘(Dashboard)和用户管理(Users) 界面。

App.js 中定义了应用的顶级路由结构,使用 Routes 来定义两个主要路由路径:* 和 /admin/*。每个路径指向对应的 MainSite 和 AdminPanel 组件。* 路径指向 MainSite 组件,该组件处理与主站相关的子路由。/admin/* 路径指向 AdminPanel 组件,该组件处理与管理面板相关的子路由。

当访问 / 时,展示 MainSite 组件和 Home 组件;访问 /about,展示 MainSite 组件和 About 组件;访问 /admin,展示 AdminPanel 组件;访问 /admin/dashboard,展示 AdminPanel 组件和 Dashboard 组件。

3. 布局路由

布局路由是一种组织和管理路由的方式,它允许开发者将路由与其对应的布局分开管理。这在复杂的应用中特别有用,因为它可以帮助保持代码的清晰和模块化。

布局路由是指一种模式,其中一组路由共享相同的布局组件。这意味着这些路由的所有页面都将有相同的外观和感觉,例如共享的头部和底部导航栏。布局组件负责渲染这些共享元素,而特定的子路由则负责渲染页面的主要内容。

例3-3 升级版管理系统案例

App.js

同案例3-2。

MainSite.js

import React from 'react';
import {Routes, Route, Link} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Header from './Header';
import Footer from './Footer';
import Error from "./Error";

function MainSite() {
  return (
    <div>
      <Header />
      <nav>
        <Link to="/">Home</Link> |
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        {/* 更多主站的路由可以在这里添加 */}

        {/* 捕获所有未匹配的路由并显示 Error 组件 */}
        <Route path="*" element={<Error />} />
      </Routes>
      <Footer />
    </div>
  );
}

export default MainSite;

AdminPanel.js

import React from 'react';
import {Routes, Route, Link} from 'react-router-dom';
import Dashboard from './Dashboard';
import Users from "./Users";
import AdminHeader from './AdminHeader';
import AdminFooter from './AdminFooter';
import Error from "./Error";

function AdminPanel() {
  return (
    <div>
      <AdminHeader />
      <nav>
        <Link to="/admin">Dashboard</Link> |
        <Link to="/admin/users">Users</Link>
      </nav>
      <Routes>
        <Route path="" element={<Dashboard />} />
        <Route path="users" element={<Users />} />
        {/* 更多管理面板的路由可以在这里添加 */}
        {/* 捕获所有未匹配的路由并显示 Error 组件 */}
        <Route path="*" element={<Error />} />
      </Routes>
      <AdminFooter />
    </div>
  );
}

export default AdminPanel;

上述案例中,我们在 MainSite 和 AdminPanel 中加入了 Header 和 Footer 布局组件,同时添加了一个用于处理所有未匹配路由的 Error 组件。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
React Router是一个用于建立SPA应用程序的库,它提供了一种将应用程序状态与URL同步的方式。React Router v6React Router的最新版本,它引入了一些新的概念和语法。 下面是使用React Router v6搭建路由的步骤: 1. 安装React Router v6 使用npm或者yarn安装React Router v6: ``` npm install react-router-dom@next ``` 2. 创建路由 在应用程序的入口文件中,使用BrowserRouter创建一个路由: ```jsx import { BrowserRouter } from 'react-router-dom'; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') ); ``` 3. 定义路由 使用Route组件定义路由。Route组件的path属性指定URL的路径,component属性指定该路径对应的组件: ```jsx import { Route } from 'react-router-dom'; function App() { return ( <div> <Route path="/" component={Home} /> <Route path="/about" component={About} /> </div> ); } ``` 在上面的例子中,当URL路径为“/”时,渲染Home组件;当URL路径为“/about”时,渲染About组件。 4. 处理404页面 使用Route组件的exact属性确保路由匹配完全相等的路径。这样可以避免在匹配“/”路径时同时匹配到所有其他路径。 使用Route组件的path属性指定“*”路径,即匹配所有路径的路径。将这个Route组件放在所有其他Route组件的下面,就可以为未匹配到任何路径的URL显示404页面: ```jsx import { Route, Routes } from 'react-router-dom'; function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="*" element={<NotFound />} /> </Routes> </div> ); } ``` 在上面的例子中,当URL路径为任何未匹配到的路径时,渲染NotFound组件。 5. 嵌套路由 使用Routes组件嵌套Route组件,可以创建嵌套路由。在嵌套路由中,父级Route组件的path属性包含所有子级Route组件的path属性的前缀。 ```jsx import { Route, Routes } from 'react-router-dom'; function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />}> <Route path="team" element={<Team />} /> <Route path="history" element={<History />} /> </Route> <Route path="*" element={<NotFound />} /> </Routes> </div> ); } ``` 在上面的例子中,当URL路径为“/about/team”时,渲染Team组件;当URL路径为“/about/history”时,渲染History组件。 React Router v6引入了一些新的语法,例如使用Routes组件代替Router组件,使用element属性代替component属性等。这些语法的目的是让React Router更加简洁易用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雪月乔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值