前言

本来体验下react-router的,然后

去react-router npm查看,发现了官方的提示如下:

这个包为 React Router 提供了核心路由功能,但你可能不想直接安装它。如果您正在编写将在浏览器中运行的应用程序,您应该安装 react-router-dom。同样,如果您正在编写 React Native 应用程序,则应该安装 react-router-native。这两个都将安装 react-router 作为依赖项

也就是说如果想在react项目中添加路由功能,应该使用react-router-dom而不是react-router,直接使用最新版的react-router可能会报错

既然官方使用react-router-dom替代了react-router,那我们就学习一下怎么使用react-router-dom实现路由功能吧

快速开始

要在 Web 应用程序中开始使用 React Router,您需要一个 React Web 应用程序。如果您需要创建一个,我们建议您尝试Create React App。这是一个流行的工具,与 React Router 配合得非常好。首先,安装 create-react-app 并用它创建一个新项目

npx create-react-app demo-app
cd demo-app

安装

您可以使用 npm 或 yarn 安装 React Router。由于我们正在构建一个 Web 应用程序,因此我们将在本指南中使用 react-router-dom

npm install react-router-dom
npm run start

接下来,将以下任一示例复制/粘贴到 src/App.js。

第一个例子:基本路由

import React from "react";
import {BrowserRouter as Router,Switch,Route,Link
} from "react-router-dom";export default function App() {return (<Router><div><nav><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li><li><Link to="/users">Users</Link></li></ul></nav>{/* <Switch>标签会渲染将匹配URL的第一个<Route>进行渲染,如果最前面的<Route>匹配了,后面的就不会渲染,所以对于path="/"的<Route>应该放在最后面,<Switch>相当于js里的switch */}<Switch><Route path="/about"><About /></Route><Route path="/users"><Users /></Route><Route path="/"><Home /></Route></Switch></div></Router>);
}function Home() {return <h2>Home</h2>;
}function About() {return <h2>About</h2>;
}function Users() {return <h2>Users</h2>;
}

在这个例子中,我们有 3 个由路由器处理的“页面”:一个主页、一个关于页面和一个用户页面。当您在不同的 <Link> 上点击时,路由器会渲染匹配的 <Route>。

注意:在组件内部,<Link> 会渲染带有真实 href 的 <a>标签,因此人们使用键盘进行导航或屏幕阅读器仍然可以使用这个应用程序。

第二个例子:嵌套式路由

import React from "react";
import {BrowserRouter as Router,Switch,Route,Link,useRouteMatch,useParams
} from "react-router-dom";export default function App() {return (<Router><div><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li><li><Link to="/topics">Topics</Link></li></ul><Switch><Route path="/about"><About /></Route><Route path="/topics"><Topics /></Route><Route path="/"><Home /></Route></Switch></div></Router>);
}function Home() {return <h2>Home</h2>;
}function About() {return <h2>About</h2>;
}function Topics() {let match = useRouteMatch();return (<div><h2>Topics</h2><ul><li><Link to={`${match.url}/components`}>Components</Link></li><li><Link to={`${match.url}/props-v-state`}>Props v. State</Link></li></ul>{/* match.path和match.url一直都是"/topics"没变过,所以嵌套路由无非就是在<Route>里又渲染了一个<Route>,子<Route>需要拼接一下父<Route>的路径match.path*/}<Switch><Route path={`${match.path}/:topicId`}><Topic /></Route><Route path={match.path}><h3>Please select a topic.</h3></Route></Switch></div>);
}function Topic() {let { topicId } = useParams();return <h3>Requested topic ID: {topicId}</h3>;
}

此示例显示嵌套路由的工作原理。路由 /topics 加载 Topics 组件,该组件根据路径 :id 值有条件地渲染任何进一步的 <Route>

继续前进

希望这些示例能让您了解使用 React Router 创建 Web 应用程序是什么感觉。继续阅读以了解有关 React Router 中主要组件的更多信息!

主要组件

React Router 中的组件主要分为三类:

路由器,例如 <BrowserRouter> 和 <HashRouter>

路由匹配器,例如 <Route> 和 <Switch>

和导航,例如 <Link>、<NavLink> 和 <Redirect>

我们也喜欢将导航组件视为“路由更改器”。您在 Web 应用程序中使用的所有组件都应该从 react-router-dom 导入。

路由器Routers

每个 React Router 应用程序的核心应该是一个路由器组件。对于 web 项目,react-router-dom 提供了 <BrowserRouter> 和 <HashRouter> 路由器。两者之间的主要区别在于它们存储 URL 以及与您的 Web 服务器通信的方式。

<BrowserRouter> 使用常规 URL 路径。这些通常是最好看的 URL,但它们需要正确配置您的服务器。具体来说,您的 Web 服务器需要在由 React Router 客户端管理的所有 URL 上提供相同的页面。 Create React App 在开发中支持开箱即用,并附带有关如何配置生产服务器的说明。

<HashRouter> 将当前位置存储在 URL 的哈希部分中,因此 URL 看起来类似于 http://example.com/#/your/page。由于哈希从未发送到服务器,这意味着不需要特殊的服务器配置。

要使用路由器,只需确保它在元素层次结构的根部渲染。通常,您会将顶级 <App> 元素包装在路由器中,如下所示:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";function App() {return <h1>Hello React Router</h1>;
}ReactDOM.render(<BrowserRouter><App /></BrowserRouter>,document.getElementById("root")
);

路由匹配器

有两个路由匹配组件:Switch 和Route。当 <Switch> 被渲染时,它会搜索它的子 <Route> 元素以找到路径与当前 URL 匹配的元素。当它找到一个时,它会渲染那个 <Route> 并忽略所有其他的。这意味着您应该将具有更具体(通常更长)路径的 <Route> 放在不太具体(范围广)的路径之前。如果没有 <Route> 匹配,则 <Switch> 不渲染任何内容(空)。

匹配优先级

有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照<Route>的排列顺序:<Route>排列得越靠前,优先级就越高。

import React from "react";
import ReactDOM from "react-dom";
import {BrowserRouter as Router,Switch,Route
} from "react-router-dom";function App() {return (<div><Switch>{/* 如果当前URL为/about,则渲染此<Route>其余的都被忽略了 */}<Route path="/about"><About /></Route>{/* 注意这两个<Route>是如何排列的。更具体的path=“/contact/:id”位于path=“/contact”之前,因此查看单个联系人时将渲染当前<Route> */}<Route path="/contact/:id"><Contact /></Route>{/*   注意/contact会匹配当前<Route>,而不是上一个*/}<Route path="/contact"><AllContacts /></Route>{/* 如果之前的任何路径都不渲染任何内容,这条路径起到了退路的作用。重要提示:路径为“/”的路由将始终匹配URL,因为所有URL都以/开头。那就是为什么我们把这个放在最后,可以当404页面 */}<Route path="/"><Home /></Route></Switch></div>);
}ReactDOM.render(<Router><App /></Router>,document.getElementById("root")
);

需要注意的一件重要事情是 <Route path> 匹配 URL 的开头,而不是整个内容。所以 <Route path="/"> 将始终匹配 URL。因此,我们通常将这个 <Route> 放在 <Switch> 的最后。另一种可能的解决方案是使用与整个 URL 匹配的 <Route exact path="/">。

注意:虽然 React Router 确实支持在 <Switch> 之外渲染 <Route> 元素,但从 5.1 版开始,我们建议您改用the useRouteMatch 钩子。此外,我们不建议您在没有路径的情况下渲染 <Route>,而是建议您使用钩子来访问您需要的任何变量。

导航(或路由转换器)

React Router 提供了一个 <Link> 组件来在你的应用程序中创建链接。无论您在何处渲染 <Link>,都将在您的 HTML 文档中呈现一个锚点 (<a>)。

<NavLink> 是一种特殊类型的 <Link>,当它的 to prop 匹配当前位置时,它可以将自己设置为“活动”。

<Link to="/">Home</Link>
// <a href="/">Home</a>
<NavLink to="/react" activeClassName="hurray">React
</NavLink>// 当URL是/react, 它渲染的是:
// <a href="/react" className="hurray">React</a>// 否则:
// <a href="/react">React</a>
<Redirect to="/login" />

任何时候你想强制导航,你都可以渲染一个 <Redirect>。当 <Redirect> 渲染时,它将使用它的 to prop 进行导航。

钩子函数

React Router 附带了一些钩子,可让您访问路由器的状态并从组件内部执行导航。

请注意:您需要使用 React >= 16.8 才能使用这些钩子中的任何一个, 并且这四个钩子函数只能在<Router>或者被<Router>包裹的子组件里使用,否则就会报错

useHistory

useLocation

useParams

useRouteMatch

useHistory

useHistory 钩子函数会返回一个history实例,通过这个实例你可以进行跳转操作

import { useHistory } from "react-router-dom";function HomeButton() {let history = useHistory();function handleClick() {history.push("/home");}return (<button type="button" onClick={handleClick}>Go home</button>);
}

useLocation

useLocation钩子函数会返回一个location对象,location对象里有当前路径信息,你可以把useLocation想象成useState,当路由改变的时候useLocation都会返回一个最新的地址对象

import React from "react";
import ReactDOM from "react-dom";
import {BrowserRouter as Router,Switch,useLocation
} from "react-router-dom";function usePageViews() {let location = useLocation();React.useEffect(() => {alert(location.pathname);}, [location]);
}function App() {usePageViews();return <Switch>...</Switch>;
}ReactDOM.render(<Router><App /></Router>,node
);

useParams

useParams会返回URL参数的键/值对象,使用它来访问当前<Route>的match.params

import React from "react";
import ReactDOM from "react-dom";
import {BrowserRouter as Router,Switch,Route,useParams
} from "react-router-dom";function BlogPost() {let { slug } = useParams();return <div>Now showing post {slug}</div>;
}ReactDOM.render(<Router><Switch><Route exact path="/"><HomePage /></Route><Route path="/blog/:slug"><BlogPost /></Route></Switch></Router>,node
);

useRouteMatch

useRouteMatch 钩子尝试以与 <Route> 相同的方式匹配当前 URL。它对于在不实际渲染 <Route> 的情况下访问匹配数据非常有用

旧的写法:

import { Route } from "react-router-dom";function BlogPost() {return (<Routepath="/blog/:slug"render={({ match }) => {// Do whatever you want with the match...return <div />;}}/>);
}
使用useRouteMatch的写法:import { useRouteMatch } from "react-router-dom";function BlogPost() {let match = useRouteMatch("/blog/:slug");// Do whatever you want with the match...return <div />;
}

并且:

如果不传任何参数useRouteMatch会返回当前 <Route> 的匹配对象,就是包裹当前组件的那个<Route>匹配的对象,如果包裹当前组件的是<Routers>,那返回的是path为'/'的匹配对象,不穿传数还不如使用useLocation

或者接受一个参数,它与 matchPath 的 props 参数相同。它可以是字符串形式的路径名(如上面的示例),也可以是具有 Route 接受的匹配道具的对象,如下所示,这个时候如果匹配到了,会返回一个匹配对象,否则会返回null

const match = useRouteMatch({path: "/BLOG/:slug/",strict: true,sensitive: true
});

useRouteMatch可用于条件渲染

参考文档:

《react-router官网》

react-router-dom文档相关推荐

  1. React Router 中文文档(一)

    React Router 中文文档(一) React Router 中文文档(一) 官方英文文档 - https://reacttraining.com/rea... 版本 - v4.2.0 < ...

  2. dom文档对象手册_DOM总结

    一.DOM是一棵树,树上有Node,Node分为 Document.Element(元素)和 Text(文本),以及其他不重要的. 二.浏览器原生提供document节点,代表整个文档, 文档的第一层 ...

  3. BOM 浏览器对象模型和DOM 文档对象模型

    浏览器对象模型BOM 1. 浏览器对象模型介绍 BOM(Browser Object Model) 是指浏览器对象模型,是用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的.可 ...

  4. java dom遍历_JavaScript DOM文档遍历实战

    在介绍了<JavaScript DOM修改文档树方法实例>与<JavaScript DOM实战:创建和克隆元素>,本文将介绍JavaScript DOM文档遍历的详细知识,我们 ...

  5. JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(推荐七)

    前言 学习是有趣的,但有过滤的学习内容就更好,本博主就专门为刚接触javascript客户端编程的朋友提供及分享个人学习经历!建议大家看看:(汤姆大叔的博客) http://www.cnblogs.c ...

  6. 将XML解析成DOM文档

    在支持html5的浏览其中,可以使用标准解析器DOMParser对象进行解析html或者xml等字符串 var data = '<div></div>'; var tmp = ...

  7. day-16 jquery的DOM文档操作及bootstrap

    1. jquery的DOM文档操作 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  8. Javascript 强制浏览器渲染Dom文档

    在Cordova+Framework7开发Hybrid App时,在iPhone 7上遇到一个诡异的现象(Chrome浏览器.Android都正常):js修改手风琴中的input文本框的值后,但页面仍 ...

  9. React Redux: 从文档看源码 - Components篇

    注:这篇文章只是讲解React Redux这一层,并不包含Redux部分.Redux有计划去学习,等以后学习了Redux源码以后再做分析 注:代码基于现在(2016.12.29)React Redux ...

  10. DOM文档树和节点操作

    1 DOM文档树 1.1 DOM的定义(document object modle) DOM就是文档对象模型. /* 查看这段HTML代码中p的DOM模型 */ <html><hea ...

最新文章

  1. CVPR 2020 | 用机器学习打造计数君,谷歌RepNet可自动计数视频重复片段
  2. matlab手动抠取圆形区域_利用Photoshop通道工具扣取人物头发教程-PS抠图
  3. python整数类型-Python 的数值类型(整数、长整数、浮点数和复数)
  4. CCF-CSP 201703-1 试题名称: 分蛋糕
  5. C++中对象的构造顺序和析构顺序
  6. 1000多首无损歌曲合集
  7. VC2019编译报错 error C4996: This function or variable may be unsafe
  8. c/c++ 重载运算符 函数调用运算符
  9. 7种有害的IT团队行为,不根除就坏大事了
  10. 安卓逆向系列教程 4.9 破解内购 II
  11. 100个MySQL 的调节和优化的提示
  12. 00.Maven简介
  13. android 计算器边框,Android计算器——入门
  14. svn服务器端上传已有项目,「svn上传新项目」怎么添加新项目到SVN服务器...
  15. PDF怎么转换成CAD图纸?PDF转CAD教程
  16. 软件测试教务系统测试用例,教务管理系统测试用例.doc
  17. 【读书笔记】《读懂孩子的心》——重新了解完整的自己
  18. 用excel制作双层饼图_Excel中怎么绘制双层饼图?
  19. 【Microsoft Azure 的1024种玩法】九. Microsoft Azure云端轻松构建部署PostgreSQL数据库...
  20. 驰骋工作流签订中国航天,广东航宇卫星

热门文章

  1. 跨域问题(Vue开发中遇到的跨域问题)以及解决方法
  2. linux下光盘刻录,Linux下的光盘刻录
  3. 自学Python编程的第\七天----------来自苦逼的转行人
  4. 信奥赛1990:【19CSPS提高组】划分
  5. 2018年Google开发者大会
  6. 个税计算公式excel_我月薪1万,为啥个税只交150块捏?
  7. 2021,排名前 15 的 Vue 后台管理模板
  8. 为什么未平仓量指标很重要?因为机构投资者要来“赶牛”了!
  9. 2019 10月 月末总结
  10. giant和huge的区别