0x00 写在前面
说来很奇怪,之前用create-react-app写的web网页,结合ant desgin布局写的一个导航栏路由跳转。启动项目之后,首页有数据展示,点击导航栏可以跳转。但是!在整合了electron和react之后,启动项目之后首页空白,默认导航栏位置错误,要人为点击一下才有数据展示。这样用户体验真的真的很不友好。也是查了好久好久才解决了这个问题,于是决定写一篇博客,总结一下react-router-dom。
0x01 react-router-dom的安装与使用
react-router-dom的使用有两种方式。
1.1 使用npm
|
|
- js文件中
|
|
1.2 使用unpkg
|
|
注意的是,这种方式还需要引入react的一些核心文件和依赖文件。不推荐使用这种方式。
0x02 react-router-dom与react-router的区别
- react-router: 实现了路由的核心功能
- react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签,Link组件源码a标签行; BrowserRouter和HashRouter组件,前者使用pushState和popState事件构建路由,后者使用window.location.hash和hashchange事件构建路由。
接下来将介绍react-router-dom的一些组件
0x03 react-router-dom的详细介绍
3.1 HashRouter和BrowserRouter
这两个API两个是路由的基本,需要将它们包裹在最外层,两者只需要选其一。
3.1.1 HashRouter
使用URL的哈希部分(即window.location.hash)的
|
|
3.1.2 BrowserRouter
很多情况下不需要这个#,这时就需要用到BrowserRouter。它的原理是使用HTML5历史记录API(pushState,replaceState和popstate事件)的
|
|
- basename:string。所有位置的基本URL,如果应用程序是从服务器上的子目录提供的,则需要将其设置为子目录。 也就是说,上面例子中的Linkde解析后的href属性为 href=”#/app/about”。
- getUserConfirmation:function。用来确认导航功能。默认使用window.confirm。
- forceRefresh:bool。如果为true,则路由器将在页面导航中使用全页刷新。可以在不支持HTML5历史记录API的浏览器中使用此功能。
- keyLength:number。location.key的长度,默认为6。
- children:node。要呈现的单个子元素。
- 例如”http://localhost:3000/app/",当主页前面是有一级目录app时,同样要显示主页的内容。这时需要配合Link使用。建议使用BrowserRouter。
3.2 Route
Route用于控制路径对应显示的组件。常用的有exact、path以及component属性。
- exact用于严格匹配,控制匹配到/路径时不会再继续向下匹配;
- path标识指向的路由路径;
- component表示要跳转的路径对应的显示组件;
Route会有三大props,分别是location、history、match;
3.2.1 history
history 指的是 history 包,它是 React Router 的两个主要依赖之一(除了 React 本身),并且提供了几种不同的实现方式,用于在各种环境中管理 JavaScript 中的会话历史。
history分成以下三种
- browser history - 针对 DOM 环境,用于支持 HTML5 history API 的浏览器
- hash history - 针对 DOM 环境,用于传统的旧式(低版本) 浏览器
- memory history - history 在内存上的实现,用于测试以及 React Native 等非 DOM 环境
history对象具有以下属性和方法:
- length - number 历史堆栈中的条目数
- action - string 当前的导航操作(push、replace 或 pop)
- location - object 当前访问的位置信息,见下文
- push(path, [state]) - function 将一个新条目推入到历史堆栈中
- replace(path, [state]) - function 替换历史堆栈中的当前条目
- go(n) - function 将历史堆栈中的指针移动 n 个条目
- goBack() - function 返回到上一个页面,相当于 go(-1)
- goForward() - function 进入到下一个页面,相当于 go(1)
- block(prompt) - function 阻止导航(请参阅 history 文档)
history 对象是可变的。因此建议从
|
|
3.2.2 location
location 代表应用程序的位置。如当前的位置,将要去的位置,或是之前所在的位置。
location具有以下的属性:
- pathname - string URL 路径
- search - string URL 中的查询字符串
- hash - string URL 中的 hash 片段
- state - object 存储至 location 中的额外状态数据,仅在 browser history 和 memory history 中有效。
Router 将在以下几个地方提供 location 对象: - 在 Route component 中,以 this.props.location 方式获取
- 在 Route render 中,以 ({ location }) => () 方式获取
- 在 Route children 中,以 ({ location }) => () 方式获取
- 在 withRouter 中,以 this.props.location 方式获取
location 对象永远不会发生改变,因此可以在生命周期钩子函数中使用 location 对象来查看当前访问地址是否发生改变。
3.2.3 match
Match是在使用Router之后被放入props中的一个属性,在class创建的组件中我们需要通过this.props.match来获取match之中的信息。match中包含的信息如下。
- params: object 路径参数,通过解析 URL 中的动态部分获得键值对
- isExact: bool 为 true 时,整个 URL 都需要匹配
- path: string 用来匹配的路径模式,用于创建嵌套的 Route
- url: string URL 匹配的部分,用于嵌套的 Link
在获取id时经常使用match。
3.3 Link和NavLink
两者都可以控制路由跳转,不同点是NavLink的api更多。
3.3.1 Link
主要api是to,to可以接受string或者一个object,来控制url,表示路由要跳转的路径。
这时点击Link就会跳转到home页面。
3.3.2 NavLink:
它可以为当前选中的路由设置类名、样式以及回调函数等。
exact用于严格匹配,匹配到/则不会继续向下匹配;to则是控制跳转的路径,activeClassName是选中状态的类名,可以为其添加样式。我们通过在/home后面添加1来向路由中传递信息,这结合了上面Route中的/second/:id,线面的1234内容显示需要用到match。
3.4 Switch
Switch常常会用来包裹Route,它里面不能放其他元素,表示一次只能显示一个路由。用于渲染与路径匹配的第一个子
像这种情况,exact匹配到’/‘就不会再向下匹配,当url为”http://localhost:3000/"时,两个页面都会被匹配到;(匹配不到页面)Switch有两个属性
- location: object。用于匹配子元素而不是当前历史位置(通常是当前的浏览器 URL)的 location 对象。
- children: node。
的子元素应该是 或 。只有第一个匹配当前路径的组件会被渲染。当 中包含 时,可以使用任何 拥有的路径匹配属性:path、exact 和 strict。from 只是 path 的别名。
3.5 Redirect
Redirect有四个属性
to:string。链接到的路径名或位置。
to:object。要链接的位置。
push:bool。当为true时,重定向会将新条目推入历史记录,而不是替换当前条目
from:string。要重定向的路径名。用于在
内部渲染 时匹配位置。
0x04 结合小例子的讲解
在这个小例子中,