本文共 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-dom
和react-router-native
。其中react-router
是核心模块,集合react-router-dom
和react-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 Router
与BrowserRouter as Router
的不同,as
声名别名。
简单例子
先上个简单的例子看一下。
import React from "react";import { BrowserRouter as Router, Route, Link } from "react-router-dom";const BasicExample = () => ();const Home = () => (
- Home
- About
);const About = () => (Home
);export default BasicExample;About
简单介绍,BasicExample是对象名,也是该模块导出的模块对象, () => ();
是箭头函数或Lambda表达式。原函数是function():void{}
,即无参的函数。
前进
和后退
功能,所以所有组件都必需写在Router(具体是BrowserRouter还是HashRouter由客户定义)
标签里,即BrowserRouter 必需是最外层标签,只能这里才能前进后退
。 而且Router
下只能有一个子标签child
。 Link用于跳转,类似a标签的href的功能。Route在整体上拦截路由请求。 BrowserRouter和HashRouter路由器
BrowserRouter
和HashRouter
是Router
路由器的2种类型。
- 区别于下面要讲的路由标签
Route
。
两者区别
BrowserRouter
是使用 React-Router
的应用推荐的 history
方案。它使用浏览器中的 History API 用于处理 URL,创建一个像localhost:8080/list/123
这样真实的 URL 。这很容易出现刷新页面后报404的错误。因为真实请求会向服务器发送请求,但服务器根本没有这个页面所以会报错,这是使用BrowserRouter路由的坑点。
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. isExact
:path
是否等于 pathname
4. params
:从path-to-regexp
获取的路径中取出的值都被包含在这个对象中。 例如:
如’test/:topicId
‘中:topicId
这种写法意味着/test/后的路径名将会被获取并存在match.params.test
中。例如,路径名’/test/6’会获取到一个对象{ topicId: '6' }
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'));
render
: 一个返回React element
的函数。当匹配成功后调用该函数。该过程与传入component参数类似,并且对于行级渲染与需要向元素传入额外参数的操作会更有用。使用render参数的组件则会调用render函数。 例如 :
( )}/>
或
One
} />
- children : 一个返回React element的函数。与上述两个参数不同,无论route是否匹配当前location,其都会被渲染。用的少。
嵌套使用Route
例如
React.render((), document.body) {/* 使用 /messages/:id 替换 messages/:id */}
其中IndexRoute
匹配”/
“路径,即根目录。
路由匹配方式
- 路由器按照先后顺序匹配
- 如果使用绝对路径,可直接找到,如果使用相当路径,要从父路径开始拼完整路径。
- 路径语法
:paramName
: 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分将被作为一个参数()
:在它内部的内容被认为是可选的*
: 匹配任意字符(非贪婪的)直到命中下一个字符或者整个 URL 的末尾 例如
// 匹配 /hello/michael 和 /hello/ryan // 匹配 /hello, /hello/michael 和 /hello/ryan // 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg
Link
当你点击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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!