手挽手带你学React之React-router4.x的使用
手挽手带你学React入门三档,带你学会使用Reacr-router4.x,开始创建属于你的React项目
什么是React-router
ReactRouter是一个基于React之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与URL间的同步。通俗一点就是,它帮助我们的程序在不同的url展示不同的内容。
为什么要用React-router
我们开发的时候,不可能所有的东西都展示在一张页面上,在业务场景的要求下,我们要根据不同的URL或者不同的哈希来展示不同的组件,这个我们可以称它为路由。在我们不使用React-router的时候,我们如何去做路由呢?
我在这里给大家举个例子,不使用React-router,来实现一个简单路由。
//App.js importReact,{Component}from'react' exportdefaultclassAppextendsComponent{ constructor(){ super() //我们在App.js内部来渲染不同的组件我们这里采用哈希路由的方式,鉴于React的渲染机制,我们需要把值绑定进入state内部。 this.state={ route:window.location.hash.substr(1) } } componentDidMount(){ //这里我们通过监听的方式来监听哈希的变化,并且来更新state促进视图更新 window.addEventListener('hashchange',()=>{ console.log(window.location.hash.substr(1)) this.setState({ route:window.location.hash.substr(1) }) }) } render(){ //在这里我们定义一个RouterView所有的变化后的组件都会丢到这个RouterView中 letRouterView=App switch(this.state.route){ case'/children1': RouterView=Children break; case'/children2': RouterView=ChildrenTwo break; default: RouterView=Home break; } return() } } //为了展示效果定义子组件一 classChildrenextendsComponent{ constructor(){ super() this.state={ } } render(){ return(App
- {/*点击更改哈希值这里触发我们的监听然后修改state来触发组件的重新传染*/}
children1 children2 ) } } //为了展示效果定义子组件二 classChildrenTwoextendsComponent{ constructor(){ super() this.state={ } } render(){ return(我是子组件1
) } } //为了展示效果定义Home组件 classHomeextendsComponent{ constructor(){ super() } render(){ return(我是子组件2
我是Home
) } }
这样我们通过监听哈希变化的方式实现了我们的第一个简单路由,是不是对于路由的原理有了那么一丢丢的认识呢?接下来我们想象一个场景,这么一个路由出现了/children1/user/about/1,看到这里是不是觉得,用switchcase已经蒙B了?我们接下来就要使用到React-router了,这个东西可不需要我们自己去写一大串的switchcase了,并且性能啊,整洁度啊等等等方面都比我们自己写的好多了!
React-router初体验
首先我们在React项目文件目录下执行
npminstallreact-router-dom--save npminstallreact-router--save
要想体验一个新的东西,当然是要拿自己开刀我们改进上面我们写过的组件
//App.js importReact,{Component}from'react' //首先我们需要导入一些组件... import{HashRouterasRouter,Route,Link}from"react-router-dom"; //这里有BrowserRouter和HashRouter两种模式我比较推荐HashRouter来学习BrowserRouter需要后端配合单独前端设置刷新会出现404 //然后我们把App组件整理干净,大概成这个样子 exportdefaultclassAppextendsComponent{ constructor(){ super() this.state={ } } render(){ return() } } //为了展示效果定义子组件一 classChildrenextendsComponent{ constructor(){ super() this.state={ } } render(){ return( App
Home children1 children2 ) } } //为了展示效果定义子组件二 classChildrenTwoextendsComponent{ constructor(){ super() this.state={ } } render(){ return(我是子组件1
) } } //为了展示效果定义Home组件 classHomeextendsComponent{ constructor(){ super() } render(){ return(我是子组件2
我是Home
) } }
这里我们就完成了React-router4.X的初步体验,怎么样~我给大家的第一次的感觉还可以吧~
基本组件
Routers
在React-router4.0中,Routers有两个表现方式
{/*其余内容写在这里面*/} {/*其余内容写在这里面*/}
Route
注意,最外层的是Router这里是Route这是我们的路由匹配组件,它有两个Route和Switch
Route组件拥有多个属性,这在我们后期的路由传参中将会用到。这里我们需要简单了解几个属性pathcomponentexactstrict
path是我们匹配的地址,当地址匹配的时候我们才会去渲染component内的组件内容
path后面如果书写模式带了/:这样的内容,那么这里将会成为占位符我们可以利用占位符来取到对应路径的参数使用this.props.match.params+占位符的名字即可拿到
exact属性来规定我们是否严格匹配
strict则是严格匹配模式我们规定的路径使用/one/来书写如果没有完全匹配/one/则不会展示
//这里我们加了exact那么路径完全等于/one的时候才会渲染App/one/one/one/two后面这三种情况均不会渲染App //相反如果我们没有加exact的时候/one/one/twoApp都会被渲染 //我们加了strict以后/one将不会渲染App而如果没有strict这种情况下/one是可以渲染App的
同时React-router给我们提供了一个Switch标签在这个标签内我们只会渲染一个Route并且使第一个符合条件的Route这是什么意思呢?我们来看代码
在这样的路由下我们匹配/about会发现所有的路由都可以匹配到并且渲染了出来,这肯定不是我们想要的结果于是我们给它嵌套一个Switch
这时候我们就只会匹配到第一个/about,仅仅渲染About,大家根据实际需求去决定是否嵌套Switch使用
Link和NavLink
Link主要api是to,to可以接受string或者一个object,来控制url。我们代码里看看书写方法
//这就是路由到one搭配Router使用当然我们可以使用一个对象 //这样我们点击link不仅可以到one还可以传递一些参数
NavLink它可以为当前选中的路由设置类名、样式以及回调函数等。使用如下
//这就是路由到one搭配Router使用当然我们可以使用一个对象 //这里的exact同样是严格比配模式同Route //这样我们可以为当前选中的路由设置样式了
子路由的书写
在react-router4之前的版本,子路由通过路由嵌套就可以实现了,但是这一个方法到了React-router4中就行不通了
先来一个之前的写法,当然也是错误示例
exportdefaultclassAppextendsComponent{ constructor(){ super() this.state={ } } render(){ return() } } App
Home children1 children2 {/*在4.0以后的版本这样都会报错那么我们应该怎么写呢*/}
在react-router4.x版本中我们子路由必须要在子组件内部了
exportdefaultclassAppextendsComponent{ constructor(){ super() this.state={ } } render(){ return() } } //home内部用{this.props.match.url+子路由路径}来获取当前的路径并且加上我们要路由到的位置来进行路由匹配和路径跳转匹配这样书写Children和ChildrenTwo就是home的子路由了 classHomeextendsComponent{ constructor(){ super() } render(){ return( App
- {/*同样这两个link让他们转移到Home中我们的home组件就变成了下面的样子*/}
Home {/* */} {/* */} {/*先把这里注释掉然后我们来到Home组件内*/} ) } }我是Home
children1 children2
路由跳转
声明式跳转上面已经说过了Link和NavLink两个标签就可以满足了我们主要说一下js跳转
在4.0刚刚发布的时候this.props.history.push('路径')这个方法已经行不通了,不过值得庆幸的是,我现在所使用的4.3.1版本又可以使用这个方法来进行js路由跳转了。
我们用home组件来举个例子
classHomeextendsComponent{ constructor(){ super() } toPath=(home)=>{ console.log(123) this.props.history.push({//我们把要传参的东西都放在push对象内了 pathname:home,//我们要到达哪个路由 search:"?a=1",//明文传参的模式 query:{'type':'type'},//query对象传参 state:{//state对象传参 b:456 } }) //this.props.history.push('/123') } render(){ return() } } /*相应的我们在Children组件里面有对应的方法来获取参数。*/ classChildrenextendsComponent{ constructor(){ super() this.state={ } } render(){ console.log(this.props.match.params.id)//这种是通过路径上面的:id传过来的参数 console.log(this.props.location.query)//这是通过push的参数对象中的query传过来的和vue的query有区别它不在地址栏刷新丢失 console.log(this.props.location.state)//这是通过push的参数对象中的state传过来的它不在地址栏刷新丢失 console.log(this.props.location.search)//暴露在地址栏,需要自行处理获取数据 return({this.toPath(`${this.props.match.url}/children1/123`)}}>我是Home children1 children2 ) } }我是子组件1
总结
这一期我们主要还是讲了react-router4.x的基础使用和传参方法,react-router4.x坑比较多,不过使用熟练了会让你感觉很爽,大家不要吝啬自己的时间多多学习。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。