React-router V4.0

React Router更新到4.0,使用起来发生了很大的变化,这个变化只要是指完全的组件化-----嵌套的JSX路由器!接下来,像刚接触路由一样的姿势,一探究竟(文字太小,建议大家调整一下页面比例)

使用React脚手架搭建项目结构

create-react-app内在使用的npm,所以速度会很慢,你cnpm的大刀已经饥渴难耐,可以考虑设置npm为cnpm镜像源:

npm config set registry http://registry.npm.taobao.org/
//通过get registy检测是否成功
npm get registry
>http://registry.npm.taobao.org/

生成的项目结构src目录如下

React-router V4.0_第1张图片
a.png

因为来回切换页面可能会破坏读文的愉悦心情,所以咱们主要在app.js内部大动手脚

app.js基本内容
import React,{Component} from "react";


//创建App根组件
class App extends Component{
    render(){
        return(
            

hello React!

) } } export default App;

控制台输入

npm start

项目已经启动,不接受任何形式的报错

下载react-router
cnpm install react-router-dom --save

在app.js内部引入

import React,{Component} from "react";

//引入路由组件
import { BrowserRouter, Route,Link} from 'react-router-dom';

//创建App根组件
class App extends Component{
    render(){
        return(
            

hello React!

) } } export default App;

接下来我创建函数式组件作为页面级组件

//首页组件
let Index=()=>{
    return(
        

我是首页内容

) } //列表组件 let List=()=>{ return(

我是列表页

  • 我是列表元素
  • 我是列表元素
  • 我是列表元素
) }

在App组件内部配置路由组件

class App extends Component{
    render(){
        return(
            
                

hello React!

首页 列表页
) } }

注意:

  • BrowserRouter内部只能放一个子元素
  • Route组件类似于判断,路径符合的会被显示
1.如果没有匹配到路径怎么办?

当然是显示空白,但是使用组件
路由引入改为

//引入路由组件
import { BrowserRouter, Route,Link,Redirect} from 'react-router-dom';

App写成


        

hello React!

首页 列表页

这样当匹配不到路径的时候会被重定向到/index

2.我想把Index组件path定义为/可以吗?

当然可以,只不过需要注意一些问题


        

hello React!

首页 列表页

浏览器访问,大家会发现,两个组件同时出现,这是因为路由进行的是非精准匹配

//假设为组件path
let str="/list/hot";
let str2="/list/discount";
//假设为真实访问路径
let path="/list";
//假设为Route组件判断
if(str.indexOf(path+"/")==0){
      alert("str")
}
if(str2.indexOf(path+"/")==0){
      alert("str2")
}
// 真实路径  /             path:/   
// 真实路径  /list         path:/  /list  
// 真实路径  /list/abc     path:/  /list  /list/abc

毫无悬念,会弹出两次,相信也都已经理解了,怎么解决这个问题?

1.exact

给Route组件添加exact进行精准匹配,相当于

path==str1
path==str2

你可能觉得非精准匹配的存在是一个烦恼,其实到嵌套路由时它的作用就凸显出来了

App组件代码


        

hello React!

首页 列表页
2.Switch

只显示一个,匹配成功之后不再往下查找,但是不是精准查找,实际开发过程中需要加上exact

路由引入改为

//引入路由组件
import { BrowserRouter, Route,Link,Redirect,Switch} from 'react-router-dom';

App写成


        

hello React!

首页 列表页

说完Route组件再来看一下Link,这个组件最终会被解析成a标签,在有些场景下使用会很受限,例如程序执行到某个环节需要路由进行跳转,类似location.href或者说Vue中的router.push。BrowserRouter组件外层包括,将路由信息注入到每个路由组件的props上。接下来将Link换成button

注意:因为App组件不是路由组件,所以该组件内部的props访问不到路由信息

对组件嵌套结构进行改造:

//创建Content组件
class Content extends Component{
    constructor(props){
        super(props);
        console.log(props);
    }
    render(){
        return(
            

hello React!

) } } //创建App根组件 class App extends Component{ render(){ return( ) } }
withRouter

如上代码,用Route组件包括Content组件将路由信息注入组件。组件内部需要访问路由对象时这样做就太过麻烦了,默认情况下,只有经过路由匹配渲染的组件才能访问路由对象下的属性和方法,然而不是所有组件都与路由相连,我们可以使用withRouter将路由对象注入到组件

首先引入withRouter

//引入路由组件
import { BrowserRouter, Route,Link,Redirect,Switch,withRouter} from 'react-router-dom';

上述代码修改如下

//创建Content组件
class Content extends Component{
    constructor(props){
        super(props);
        console.log(props);
    }
    render(){
        return(
            

hello React!

) } } //将路由对象注入到组件 Content=withRouter(Content) //创建App根组件 class App extends Component{ render(){ return( //这里直接使用组件即可 ) } }
Link or NavLink

在4.0版本中,这两个组件都可以解析为a链接进行页面跳转,工作方式相同,但是NavLink可以根据路由匹配提供一些样式功能,代码如下


        

hello React!

Index List

当匹配路径为/时对应a链接会有active类名,生效对应样式

Route

Route组件通过上面的使用,应该不陌生了,匹配路径显示对应组件,基础用法存在一些局限性:

1.当需要往路由组件额外传一些props

这种写法在List组件内部是接收不到age


需要借助render属性

{
        return 
}}>

render指向一个函数式组件将List组件返回,这样就可以在List组件上随意定义props,此种情况下List不再属于路由组件,所以访问不到路由相关对象,但是箭头函数props中包含路由相关信息,所以

{
        return 
}}>

一切照常进行

2.当在匹配跳转之前进行一些拦截时(如登录验证)
{
        if(this.state.login){//根据登录状态决定如何响应
                return ()    
        }else{
                return()
        }  
}}>

加油!

你可能感兴趣的:(React-router V4.0)