模块开发之react-router使用(八)
发布日期:2021-06-29 14:16:10 浏览次数:2 分类:技术文章

本文共 5794 字,大约阅读时间需要 19 分钟。

模块开发之react-router使用(八)

前言

路由其实决定了链接跳转到哪个界面。

比如http://localhost:8080/app/list,正常情况下链接发送到后端,由后端决定返回的页面,但由于现在前端技术的发展,模块化开发,前端可以自己决定返回的页面内容,这就是本文需要解释的路由的概念。即路由决定跳转到哪个界面。

路由是用来区分一个网站不同功能模块的地址,浏览器通过访问同一站点下的不同路由,来访问网站不同的功能。同样路由也让开发者区分返回的内容。

·React-router是一个非常好有的路由插件,它从整体上管理整个应用上的路由跳转。

前端路由如何实现的?

HTML5 API中的history能够让我们控制url跳转之后并不刷新页面,而是交给我们JS代码进行操作。意思是说history能监听并拦截url跳转,转而交给js操作。
本文件使用ES6模块加载方式,不是CommonJS,CMD,AMD模块规范。React-Router4由3部分组件,react-router,react-router-domreact-router-native。其中react-router是核心模块,集合react-router-domreact-router-native功能在一起,网络开发只要引入react-router-dom即可,他已经暴露了react-router核心模块里接口

引入模块

EC6引入模块方式

import { HashRouter as Router, Route, Switch, Redirect } from 'react-router-dom'

import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'

2种方式只有HashRouter as RouterBrowserRouter as Router的不同,as声名别名。

简单例子

先上个简单的例子看一下。

import React from "react";import { BrowserRouter as Router, Route, Link } from "react-router-dom";const BasicExample = () => (  
  • Home
  • About

);const Home = () => (

Home

);const About = () => (

About

);export default BasicExample;

简单介绍,BasicExample是对象名,也是该模块导出的模块对象, () => ();是箭头函数或Lambda表达式。原函数是function():void{},即无参的函数。

下面是关于react-router相关概念。
由于每个路由器都会维护一个History对象,其实作用是为了前进后退功能,所以所有组件都必需写在Router(具体是BrowserRouter还是HashRouter由客户定义)标签里,即BrowserRouter 必需是最外层标签,只能这里才能前进后退
而且Router下只能有一个子标签child
Link用于跳转,类似a标签的href的功能。Route在整体上拦截路由请求。

BrowserRouter和HashRouter路由器

BrowserRouterHashRouterRouter路由器的2种类型。

2种路由的特点
1. 只能有一个子child.比如

  1. 区别于下面要讲的路由标签Route

两者区别

BrowserRouter是使用 React-Router 的应用推荐的 history方案。它使用浏览器中的 History API 用于处理 URL,创建一个像localhost:8080/list/123这样真实的 URL 。这很容易出现刷新页面后报404的错误。因为真实请求会向服务器发送请求,但服务器根本没有这个页面所以会报错,这是使用BrowserRouter路由的坑点。

想解决这个问题参考这里,其本质的原理就是利用服务端将任何请求都指向index.html,而在React应用中index.html又刚好通过React-Router配置了相应的路由,我们让服务器返回index.html,后面就交给前端路由来实现无刷新加载对应页面。

HashRouter使用 URL 中的 hash(#)部分去创建路由,举例来说,用户访问本地服务/about,实际会看到的是http://localhost/#/about

总结一下

假如有一个 Link 标签,点击后跳转到 /test/about。

BrowserRouter: http://localhost:8080/test/about

HashRouter: http://localhost:8080/#/test/about
如果有服务器端的动态支持,建议使用 BrowserRouter,否则建议使用 HashRouter。

Route

要点:

1. 可以放在页面任意位置
2. 匹配URL里的路径名(即域名之后部分),只要匹配就会被渲染,除非在条件语句里。
3. Route标签更多的用于渲染页面,跳转用Link
语法如下

exact:可选参数,决定是否是精确匹配,不填就是模糊匹配,

例如<Route path="/test" component={Test} />
1. 当路径名为’/’时, path不匹配
2. 当路径名为’/test''/test/1'时, path匹配

若只想匹配/test则使用exact参数,即<Route exact path="/test" component={Test} />

match值对象

当匹配成功后,匹配的结果封装到一个叫match对象里。而这个match对象可以传到component对象的react组件里。

match包含的信息有如下几点:
1. url :与当前location路径名所匹配部分
2. path :路由的地址
3. isExactpath 是否等于 pathname
4. params :从path-to-regexp获取的路径中取出的值都被包含在这个对象中。

例如:

如’test/:topicId‘中:topicId这种写法意味着/test/后的路径名将会被获取并存在match.params.test中。例如,路径名’/test/6’会获取到一个对象{ topicId: '6' }

而Topic组件声明,接收match对象,获得topicId值如下:

const Topic = ({ match }) => (  

{match.params.topicId}

);

不同的组件提供形势访问方式不同

Route component组件使用 this.props.match
Route render纯函数使用match对象 as ({ match }) => ()
Route children 一个返回React element的函数使用match对象as ({ match }) => ()

Route渲染组件3种方式方式

当满足path条件时,决定渲染哪个React组件有3种方式,其实是指定不同的参数

1. component : 指定React组件。即component={组件名},最终使用React.createElement创建。例如<Route path="/test" component={Test} />
这个使用的比较多,但有注意传入的是组件还是组件标签
当您使用组件(而不是下面的渲染或子项)时,路由器使用React.createElement从给定组件创建一个新的React元素。
这意味着如果您向组件属性提供内联函数,则可以在每个渲染中创建一个新组件.这将导致现有组件卸载和新组件安装,而不是仅更新现有组件
当使用内联函数进行内联渲染时,请使用render或child
比如

const About = () =>

About

;const Company = () =>

Company

;const User = ({ match }) => (

User: {match.params.user}

);

这种使用方法是OK的,因为返回的不是React组件而是div标签,如果返回的React组件标签,这种使用方式会造成制裁和重装安装。

注意React是渲染HTML标签和React组件时,以组件名大小写区别的,不是变量名

//渲染HTMLvar myDivElement = 
;ReactDOM.render(myDivElement, document.getElementById('example'));//渲染React。myElement是小写的,但组件MyComponent是大写的。var MyComponent = React.createClass({/*...*/});var myElement =
;ReactDOM.render(myElement, document.getElementById('example'));
  1. render : 一个返回React element的函数。当匹配成功后调用该函数。该过程与传入component参数类似,并且对于行级渲染与需要向元素传入额外参数的操作会更有用。使用render参数的组件则会调用render函数。
    例如 :
(
)}/>

One

} />
  1. children : 一个返回React element的函数。与上述两个参数不同,无论route是否匹配当前location,其都会被渲染。用的少。

嵌套使用Route

例如

React.render((  
{/* 使用 /messages/:id 替换 messages/:id */}
), document.body)

其中IndexRoute匹配”/“路径,即根目录。

路由匹配方式

  1. 路由器按照先后顺序匹配
  2. 如果使用绝对路径,可直接找到,如果使用相当路径,要从父路径开始拼完整路径。
  3. 路径语法
    • :paramName : 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分将被作为一个参数
    • () :在它内部的内容被认为是可选的
    • * : 匹配任意字符(非贪婪的)直到命中下一个字符或者整个 URL 的末尾
      例如
// 匹配 /hello/michael 和 /hello/ryan
// 匹配 /hello, /hello/michael 和 /hello/ryan
// 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg

当你点击Link时,URL会更新,组件会被重新渲染,但是页面不会重新加载。只要用在TAB页面或导航页上切换页面

语法

一个基本的location对象为{ pathname: '/', search: '', hash: '', key: 'abc123' state: {} }

当直接输入字符串路径例如/login,会转换成location对象{ pathname: '/login'}
尽量使用绝对路径,即“/路径

router渲染组件方式问题

react-router每次打开新的界面都会重新渲染组件。因为Route 对应path 没有匹配时会卸载掉注册的组件,在重新match 时重新挂载,也会造成刷新的情况。比如

import React from 'react';class About extends React.Component {
componentDidMount () { console.log('mount'); } componentWillUnmount () { console.log('un mount'); } render () { return (

This is About page.

); }};export default About;

在切换到 /about 页面的时候,会打印出 mount,而当离开页面的时候会打印出 un mount。路由的这种进入时装载组件离开时卸载组件的策略就可以做到合理利用「资源」,不会一下把所有的组件都装载进来使内存占用飙升,也不会离开时没有卸载而时内存泄漏。

但如果不想重新渲染整个组件的话,可以使用国人写的router缓存框架
使用方法是安装模块npm install react-router-cache-route --save
使用CacheRoute代替Router,使用CacheSwitch代替Switch

转载地址:https://chenyuan.blog.csdn.net/article/details/80704641 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:模块开发之React入门使用(五)
下一篇:前端模块开发之ES6特性(七)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月23日 20时31分33秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

开源项目|RT-Thread 软件包应用作品:小闹钟 2019-04-29
在 RT-Thread Studio 上使用 RT-Thread Nano 2019-04-29
开源项目|软件包应用作品:通用物联网系统平台 2019-04-29
【经验分享】RT-Thread UART设备驱动框架初体验(中断方式接收带\r\n的数据) 2019-04-29
单片机里面的CPU使用率是什么鬼? 2019-04-29
推荐一个优质Linux技术公众号-作者都是一线Linux代码贡献者们哦 2019-04-29
RT-Thread 编程风格指南 2019-04-29
95后高校电子教师,软硬兼修有趣有料! 2019-04-29
使用 STM32 通用 Bootloader ,让 OTA 更加 Easy 2019-04-29
Cache 的基本概念与工作原理 2019-04-29
装机量超亿台 RISC-V +IoT OS!中科蓝讯与RT-Thread战略合作,共推自主物联网生态发展 2019-04-29
Android程序员必备!面试一路绿灯Offer拿到手软,Android面试题及解析 2019-04-29
Android程序员的春天!12个View绘制流程高频面试题,分享PDF高清版 2019-04-29
深入交流安卓!新鲜出炉的Android面试真题集锦我给你们整理出来了!Android面试题及解析 2019-04-29
深入浅出Android开发!你会的还只有初级工程师的技术吗?一线互联网公司面经总结 2019-04-29
深度剖析原理!超全Android中高级面试复习大纲,含BATJM大厂 2019-04-29
温故而知新!Android开发者该学习哪些东西提高竞争力?成功入职阿里 2019-04-29
火爆知乎的Android面试题-Android-App的设计架构经验谈,大厂内部资料 2019-04-29
看完直接怼产品经理!Android多进程从头讲到尾,跳槽薪资翻倍 2019-04-29
快速从入门到精通!面试的时候突然遇到答不上的问题怎么办?已拿到offer 2019-04-29