React学习笔记(七) React Router

简介: React学习笔记(七) React Router


1、安装


ReactRouter 是一个基于 React 的路由库,它被拆分为三个独立的包,分别是:

  • react-router-dom:提供 Web 应用所需的特定组件
  • react-router-native:提供移动应用所需的特定组件
  • react-router-core:提供核心的路由组件


我们可以使用 Create React App 工具快速搭建一个脚手架作为练习的环境

> npm install -g create-react-app
> create-react-app my-project
> cd my-project


然后使用 NPM 在项目中添加 React Router(这里只需安装 react-router-dom 即可)

> npm install --save react-router-dom


这样我们就可以在 src/App.js 文件中写下我们的练习代码啦(直接用练习代码替换掉原文件内容就好)


2、入门


组件化的思维无处不在,路由的使用也是一样的,我们可以通过组件定义路由

在 React Router 中有三种基础组件,分别是 路由器组件路由匹配组件导航组件

我们先来看一个简单的例子

import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
function Index() { return <h3>Home</h3> }
function About() { return <h3>About</h3> }
function Users() { return <h3>Users</h3> }
function App() {
  return (
    <BrowserRouter>
      {/* 路由器组件 BrowserRouter */}
      {/* 注意,路由器组件只能有一个子元素,所以我们一般会使用 <div> 将元素包裹起来 */}
      <div>
        {/* 导航组件 Link,用于在前端页面展示导航样式,类似 <a> 标签 */}
        {/* to 属性指定 URL 路径 */}
        <Link to="/">Home</Link><br />
        <Link to="/about/">About</Link><br />
        <Link to="/users/">Users</Link><br />
        {/* 路由匹配组件 Route,用于定义路由匹配规则,并在路径匹配成功后渲染组件 */}
        {/* path 属性指定匹配的路径,component 属性指定使用的组件 */}
        <Route path="/" exact component={Index} />
        <Route path="/about/" component={About} />
        <Route path="/users/" component={Users} />
      </div>
    </BrowserRouter>
  )
}
export default App;


3、路由器组件


对于 Web 应用而言,react-router-dom 提供两种类型的路由器组件,

一般而言 适用于 管理动态请求 的网站, 适用于 呈现静态文件 的网站

每个 router 都会创建一个 history 对象用于跟踪当前 location,当 location 发生变化时就会重新渲染网页

路由器组件是 React Router 的核心组件,其它任何组件都必须包裹在路由器组件内使用


4、路由匹配组件


路由匹配组件用于定义路由匹配规则,react-router-dom 同样提供两种组件,<Route><Switch>


(1)<Route>


我们先来回顾一下上面的例子:

<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />


<Route> 组件有两个常用的属性,分别是 pathcomponent,它们的语义也很简单

就是当路径名与 path 属性定义的路径匹配时,渲染 component 属性定义的组件;若不匹配则渲染 null

什么才是 匹配的路径 呢?这里举一个例子,假设 path 定义的路径为 /about/,那么

  • 当路径名为 /ab 时,path 不匹配
  • 当路径名为 /about 时,path 匹配
  • 当路径名为 /about/un,path 匹配

很简单,对吧!只要开头一样,path 就能匹配,但是这样会产生一个 多匹配的问题

什么意思呢?我们再来举一个例子,假设我们现在访问路径 /about,很显然我是希望程序只显示 About 组件的

但由于路径 //about/ 都能匹配,所以程序最终会渲染出 Index 和 About 组件,这显然不符合我们的意图

这时候,exact 属性 就可以派上用场啦,它用来指明匹配的路径必须完全一致才算匹配成功

也就是说,为第一个路由匹配组件添加 exact 属性后,当我们访问路径 /about 时,程序就只会显示 About 组件


(2)<Switch>


如果我们希望一次渲染一个组件,我们可以给 <Router> 包裹一个 <Switch> 组件

这样,它将按照路由定义的顺序进行匹配,并且当成功匹配到一个路由后停止匹配

<Switch>
  <Route path="/" exact component={Index} />
    <Route path="/about/" component={About} />
    <Route path="/users/" component={Users} />
</Switch>


5、导航组件


导航组件用于在页面展示导航样式,react-router-dom 提供两种常用组件,<Link><NavLink>


(1)<Link>


我们还是回顾一下上面的例子:

<Link to="/">Home</Link><br />
<Link to="/about/">About</Link><br />
<Link to="/users/">Users</Link><br />

<Link> 组件很容易理解,它的作用和显示的样式与 <a> 标签十分相似

<Link> 组件有一个常用的属性 to,用于定义要跳转到的路径


(2)<NavLink>


<NavLink><Link> 的一种特殊类型,除了有一个常用的 to 属性之外

它还有一个 activeClassName 属性,用于定义当路径匹配后使用的样式


6、URL 参数


我们可以使用 :参数名称 为路径定义参数,例如 <Route path="/users/:username" component={Users} />

那么,当路径名为 /user/Alice 时,path 可以匹配;当路径名为 /user/Bob 时,path 也可以匹配

并且,在路由匹配成功后可以给 Users 组件传入参数 match 对象 以获取匹配的参数

import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
function Users({ match }) {
    console.log(match)
    return <h3>Hello { match.params.username }</h3>
}
function App() {
  return (
    <BrowserRouter>
      <div>
        <h3>User</h3>
        <Link to="/users/Alice">To Alice</Link><br />
        <Link to="/users/Bob">To Bob</Link><br />
        <Route path="/users/:username" component={Users} />
      </div>
    </BrowserRouter>
  )
}
export default App;


当路径为 /users/Alice 时,我们来看看 match 对象 包含了什么内容

{
    isExact: true, // 是否为 exact 模式
    params: { username: "Alice" }, // URL 参数
    path: "/users/:username", // 定义的路径
    url: "/users/Alice", // 真实的路径
    __proto__: Object
}


7、查询参数


我们可以使用 ?查询字符串 定义查询参数,例如

<Link to="/users?name=Alice">To Alice</Link>


我们也可以为 <Link> 组件的 to 属性传入一个对象,在其中指定查询字符串,例如

<Link to={{ pathname: "/user", search: "?name=Bob" }}>To Bob</Link>


然后,在路由成功匹配后可以给组件传入 location 对象 以获取匹配的参数

import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
function Users({ location }) {
    console.log(location)
    return <h3>Hello { location.search.split('?')[1].split('=')[1] }</h3>
}
function App() {
  return (
    <BrowserRouter>
      <div>
        <h3>User</h3>
        <Link to="/users?name=Alice">To Alice</Link><br />
        <Link to={{ pathname: "/users", search: "?name=Bob" }}>To Bob</Link><br />
        <Route path="/users" component={Users} />
      </div>
    </BrowserRouter>
  )
}
export default App;


当路径为 /users?name=Alice 时,我们来看看 location 对象 包含了什么内容

{
    key: "3qrwxq",
    pathname: "/users", // 匹配的路径名称
    search: "?name=Alice", // 查询参数(?后面的内容)
    hash: "", // 锚点参数(#后面的内容)
    __proto__: Object
}


8、重定向


import React from "react";
import { BrowserRouter, Route, Switch, Link, Redirect } from "react-router-dom";
function Matched() { return <h3>Matched!</h3> }
function App() {
  return (
    <BrowserRouter>
      <div>
        <Link to="/old-match">Old Match</Link> (to be redirected)<br/>
        <Link to="/new-match">New Match</Link><br/>
        <Switch>
          {/* 当路径匹配到 `/old-match` 时,重定向到 `/new-match` */}
          <Redirect from="/old-match" to="/new-match" />
          <Route path="/new-match" component={ Matched } />
        </Switch>
      </div>
    </BrowserRouter>
  )
}
export default App;


9、防止转换


import React from "react";
import { BrowserRouter, Route, Switch, Link, Prompt } from "react-router-dom";
function Home() {
  return (
    <div>
      <h3>Home Page Here!</h3>
      <Link to="/about">To About Page</Link>
    </div>
  )
}
function About() {
  return (
    <div>
      <h3>About Page Here!</h3>
      <Link to="/">Return Home Page</Link>
      {/* 不会实际渲染出来,但是在路径发生改变时会弹出提示信息 */}
      <Prompt message={ `Are you sure you want to go to Home Page?`  } />
    </div>
  )
}
function App() {
  return (
    <BrowserRouter>
      <div>
        <Switch>
          <Route path="/" exact component={ Home } />
          <Route path="/about" component={ About } />
        </Switch>
      </div>
    </BrowserRouter>
  )
}
export default App;


10、路由配置

import React from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
// 1、定义组件
function Home() { return <h2>Home Page</h2> }
function About({ routes }) { // 包含嵌套路由
  return (
    <div>
      <h2>About Page</h2>
      <Link to="/about/team">To Team</Link><br />
      <Link to="/about/product">To Product</Link><br />
      { routes.map((route, index) => ( <RouteWithSubRoutes key={index} {...route} /> )) }
    </div>
  )
}
function Team() { return <h3>This is our team</h3> }
function Product() { return <h3>This is our product</h3> }
// 2、定义路由配置
const routes = [
  {
    path: "/home",
    component: Home
  },
  {
    path: "/about",
    component: About,
    routes: [
      {
        path: "/about/team",
        component: Team
      },
      {
        path: "/about/product",
        component: Product
      }
    ]
  }
]
// 3、处理嵌套路由
function RouteWithSubRoutes(route) {
  return <Route path={route.path} render={ (props) => ( <route.component {...props} routes={route.routes} /> )} />
}
// 4、传入路由配置
function App() {
  return (
    <BrowserRouter>
      <div>
        <Link to="/home">Home</Link><br />
        <Link to="/about">About</Link><br />
        { routes.map((route, index) => ( <RouteWithSubRoutes key={index} {...route} /> )) }
      </div>
    </BrowserRouter>
  )
}
export default App;


【 阅读更多关于 React Router 的内容,请参考 官方文档



目录
相关文章
|
28天前
|
资源调度 前端开发 测试技术
React Router 路由管理
【10月更文挑战第10天】本文介绍了 React Router,一个在 React 应用中管理路由的强大工具。内容涵盖基本概念、安装与使用方法、常见问题及解决方案,如路由嵌套、动态路由和路由守卫等,并提供代码示例。通过学习本文,开发者可以更高效地使用 React Router,提升应用的导航体验和安全性。
176 19
|
1月前
|
XML 前端开发 JavaScript
react学习笔记一:入门级小白到脚手架(create-react-app)开发项目
这篇文章是React的学习笔记,覆盖了从React的基础用法到高级特性,包括组件化、状态管理、生命周期、虚拟DOM等主题,适合React初学者参考。
88 0
react学习笔记一:入门级小白到脚手架(create-react-app)开发项目
|
1月前
|
前端开发 JavaScript 网络架构
实现动态路由与状态管理的SPA——使用React Router与Redux
【10月更文挑战第1天】实现动态路由与状态管理的SPA——使用React Router与Redux
32 1
|
3月前
|
移动开发 资源调度 前端开发
React Router V6 useRoutes的使用
【8月更文挑战第29天】 React Router V6 useRoutes的使用
123 3
|
3月前
|
前端开发
使用 React Router v6 进行布局
【8月更文挑战第27天】
41 1
|
3月前
|
前端开发 测试技术 开发者
React Router的神奇之处:如何用导航与路由管理让你的复杂SPA飞起来?
【8月更文挑战第31天】本文全面解析了React Router——一款用于React应用的路由与导航管理库。通过定义不同路径并依据URL渲染组件,React Router支持路径匹配、参数路由及嵌套路由等多种模式。文章详细介绍了其基本与高级用法,如使用`Link`组件导航、`Switch`组件进行路径匹配及`NavLink`自定义活动链接样式。此外,还探讨了懒加载、代码分割等性能优化技巧,并提供了简单示例代码,帮助读者快速上手。遵循本文最佳实践,开发者能够更高效地利用React Router构建复杂的单页面应用。
74 0
|
3月前
|
前端开发 UED
|
3月前
|
前端开发 JavaScript UED
什么是 React Router?
【8月更文挑战第31天】
28 0
|
5月前
|
移动开发 前端开发 Java
技术笔记:ReactNative学习笔记(一)————(RN)快速入门
技术笔记:ReactNative学习笔记(一)————(RN)快速入门
64 0
|
6月前
|
资源调度 前端开发 JavaScript
React Router:React应用的路由管理
【4月更文挑战第25天】React Router是React的官方路由库,用于管理SPA的路由。它基于组件,将URL映射到React组件,核心概念包括路由、链接和导航。设置路由时,在根组件中使用BrowserRouter或HashRouter,包裹Routes组件,定义Route规则。Link组件用于创建内部链接,实现导航。高级特性包括嵌套路由、参数化路由和编程式导航,如子路由、动态参数和JavaScript控制的导航。掌握React Router能帮助开发者更高效地构建复杂的React应用。