React Router路由
React Router路由
文章目录
一.介绍
react-router是React中用来实现路由的第三方JavaScript库,也是基于React开发的,它拥有简单的API,和强大的路由处理机制.如代码缓冲加载,动态路由匹配,以及建立正确的位置过渡处理,它可以快速地在应用中添加视图和数据流,保持页面展示内容和URL的同步
路由相关介绍,如前端路由,后断路由,以及history和hash模式参考链接
二.React-Router的使用
1.React 路由库
- react-router 核心组件
- react-router-dom 应用于浏览器端的路由库(单独使用包含了react-router的核心部分)
- react-router-native 应用于native端的路由
2.安装
-
react-router 3.X版本安装
npm install --save react-router
-
react-router 4版本安装
npm install --save react-router-dom
react-router4
版本之后,不再引入react-router
,如果是应用于浏览器端,使用react-router-dom
库,如果是native
则使用react-router-native
3.路由组件
React Router中提供了三种组件,一切皆组件
1.Router组件(路由器组件)
Router是所有路由组件共有的底层接口组件.它是路由规则制定的最外层的容器,全局只能有一个
我们使用路由时,根据不同的功能和平台对应使用哪种路由即可!
-
<BrowserRouter>
浏览器的路由组件history模式
-
<HashRouter>
URL格式为Hash路由组件 -
<MemoryRouter>
内存路由组件 -
<NativeRouter>
Native的路由组件 -
<StaticRouter>
地址不改变的静态路由组件
在我们的web应用中,我们通常使用的都是BrowserRouter或者HashRouter两种组件.
-
BrowserRouter
使用的是HTML5
的history API
(pushState,replaceState
等)对应的URL格式
http://localhost:9000/state
-
HashRouter使用的是URL的hash实现,通过锚点# 应用
对应的URL格式
http://localhost:9000/#/state
PS:使用BrowserRouter时,还需要对服务器进行配置
Router的原理:Router会创建一个history对象,history用来跟踪URL,当URL发生变化时,Router的后代组件会重新渲染.React Router中的其他组件必须作为Router组件后代进行使用,因为能够让Router组件后代访问到当前Router实例的原理就是使用了上下文(Context),所以Router的后代组件可以通过context获取history对象.
写法:Router的组件必须写在根组件的外面,将根组件包起来,而且,根组件只能有一个元素
render() {
return (
<HashRouter>
<div className="main">
</div>
</HashRouter>
);
}
2.Route组件(单个路由规则组件)
最重要的组件,作用是当location与Route的path匹配时渲染Route中的组件,每当一个组件需要根据URL决定是否渲染时,就需要创建一个Route
1.path
基本上每个Route都需要定义path属性
<Route path="/users"></Route>
相当于定义一个路由规则,当URL匹配到相应的Route时,这个Route定义的组件就会渲染出来.
2.match
当URL和Route匹配时,Route会创建一个match对象作为Props中的一个属性传递给被渲染的组件.这个对象包含下面几个属性
- params:
- isExact:表示当URL是完全匹配过来时,值为true,当URL部分匹配时值为false,通常我们可以看他的值来判断排除当前路由走得是那个路由
- path:Route的path属性
- url:匹配到的URL地址,没有域名
3.Route组件的渲染方式
-
component
component的值是一个组件,当URL和Route匹配时,Component属性定义的组件就会被渲染
<Route path="/users" component={Users}></Route>
-
render
render的值是一个函数,这个函数返回一个React元素,也就是一段JSX代码,这种方式可以为需要渲染的组件传递额外的属性
<Route path="/users" render={(props) => { <Users {...porps} info={userInfo}></Users> }}> </Route>
-
children
children的值也是一个函数,函数返回要渲染的React元素,
,与前两者不同的是,无论是否匹配成功,children返回的组件都会被渲染.如果匹配不成功时,match属性为Null看描述感觉最大的作用是:允许您根据路由是否匹配来动态调整UI,没有遇到过
4.exact
表示是否要绝对匹配,只有当路径完全匹配时才匹配
4.Switch
如果URL和多个Route匹配时,这些Route都会被渲染,如果想只匹配第一个路由规则时,我们需要
保证匹配关系,只有一个成立,避免一对多的匹配关系
我们通常会将Route包到一个Switch
组件中,并且需要完全匹配时,可以使用exact属性,也就是绝对匹配.Switch和exact经常联合使用,应用于首页导航.
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/users' component={Users}/>
<Route exact path='/about' component={Users}/>
</Switch>
注意:Switch和Route之间最好不要存在另外的标签,否则会报错,必须是直接是父子关系
5.Link
Link是React Router提供的链接组件,一个Link组件定义了当点击该Link时,页面应该如何跳转.
<Link to="/courses?sort=name" />
Link中使用to属性声明导航要到的URL地址.to属性可以是string或者object类型,当to为object时:
<Link
to={{
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: { fromDashboard: true }
}}
/>
以上使用link是声明式导航,还可以使用history对象手动实现编程式导航,history中比较常用的两个方法:
history.push('/lists') history.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
history.replace('lists') 跟 history.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
6.NavLink
与Link功能相同,但是唯一不同的是,用此组件,会有样式高亮,可以随意定义自己的高亮样式
- activeClassName 可以直接指定css类名,添加高亮样式
- activeStyle
7.Redirect
当你访问某一个路径时,自动跳转到另一个路径
{/*保证匹配关系,只有一个成立,避免一对多的匹配关系*/}
<Switch>
{/*一组匹配规则,从上到下进行匹配*/}
//重定向,一般写在路由规则最后
<Redirect from='/*' to='/'></Redirect>
</Switch>
8. withRouter的使用
withRouter是一个高阶函数,它的作用是让那些没有被Route包裹的组件拥有this.props.history等API
import React, { Component } from 'react';
//引入withRouter高阶组件
import { withRouter } from 'react-router-dom';
class Child extends Component {
To = () => {
//打印路由的history对象
console.log(this.props);
}
render() {
return (
<div>
<button onClick={this.To}>子组件按钮</button>
</div>
);
}
}
// 调用高阶组件
export default withRouter(Child);
这样就使得没有被Router包裹的组件,拥有了this.props.history
,可以操作编程式导航
9.路由懒加载
在咱们的React中,路由懒加载,有个专有的名词,叫
代码分割
,它的作用是让组件按需加载,解决了一次性就渲染所有的组件缺陷,让组件加载变成异步加载,优化性能
使用 @loadable/component
插件进行懒加载优化
npm install @loadable/component -S
需要先安装,然后引入使用
import loadable from '@loadable/component';
//动态加载组件
const Home=loadable(()=>import('./home/home'));
const Lists=loadable(()=>import('./home/list'));
PS:有时候使用这种异步加载会报babel-loader
加载的错误,需要先安装babel用来编译import异步引用方法的模块 babel-plugin-syntax-dynamic-import
npm install babel-plugin-syntax-dynamic-import -D
在.bablerc中引入syntax-dynamic-import插件
{
"presets": ["env"],
"plugins": ["syntax-dynamic-import"]
}
上一篇: Transform-style和Perspective属性
下一篇: 玩游戏 学Flex布局