React中的路由

Posted 一杯清泉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React中的路由相关的知识,希望对你有一定的参考价值。

        react推出了react-router的路由管理插件,实现了路由的核心功能,分别给web、reactnative、anywhere三个平台。 基于react-router实现的react-router-dom是给web端使用的路由,加入了在浏览器运行环境下的一些功能,核心基于history实现,分位hash路由和h5路由,其中h5路由兼容性有点差,需要后端支持,hash路由兼容行非常好,不需要后端支持。本博客介绍react路由基于react-router-dom@5.3.0,v6.0有所变化。 

一、路由组件和一般组件最大的区别

  • 写法不同

一般组件:<Demo/>
路由组件:<Route path='/demo' component=Demo

  • 一般组件不传递数据,收不到任何props的数据。
  • 路由组件不传递数据,props会收到三个重要的信息:history、location、match。

二、Link和NavLink区别

        NavLink是Link的升级版,自定义激活时的样式名,通过activeClassName="xxx"设置。

三、Switch

<HashRouter>
	<Route path='/home' component=Home/>
	<Route path='/about' component=About/>
	<Route path='/home' component=Detail/>
</HashRouter>

        路由匹配从上到下依次进行,正常情况下一个路径对应一个组件,但是路径相同会匹配多个,例如上面的/home会同时显示Home和Detail组件,引入Switch组件可以使得Route出现多个情况下匹配到第一个之后,后面的就会在执行,查找更快。

<HashRouter>
    <Switch>
        <Route path='/home' component=Home/>
        <Route path='/about' component=About/>
        <Route path='/home' component=Detail/>
    </Switch>
</HashRouter>

四、exact:精准匹配

        路由默认是模糊匹配,定义的路由如下:

<Route path='/about' component=About/>
<NavLink to='/about/a/b/c' children='About'/>

        NavLink会自动匹配到About组件,添加exact会开启严格匹配,路径必须一致。

<Route path='/about' exact component=About/>

        使用规则:发现异常在使用,不能随便开启严格匹配模式,有时候随意开启导致二级路由无法匹配。

五、Redirect

<Switch>
    <Route path='/home' component=Home/>
    <Route path='/about' component=About/>
    <Redirect to='/about'/>
</Switch>

        Redirect一般放在最后,表示重定向,如果上面都没有匹配到,就走到这,比如输入:

http://localhost:3000/

        就会走到:

http://localhost:3000/#/about

        一般使用在打开首页跳到默认选中的路由页面。

六、二级路由

<div>
    /*嵌套的二级路由需要指定一级路由的内容:/about/ */
    /*页面跳转*/
    <NavLink to='/about/hot'>热门</NavLink>
    <br/>
    <NavLink to='/about/mine'>我的</NavLink>
    
    /*定义二级路由*/
    <Switch>
        <Route path='/about/hot' component=Hot/>
        <Route path='/about/mine' component=Mine/>
        /*设置二级路由的默认项*/
        <Redirect to='/about/hot'/>
    </Switch>
</div>

七、参数传递

1、传递params参数

1). 定义向路由组件传递数

<NavLink to='/about/hot/detail/1/热门001'>热门001</NavLink>

2). 声明接收参数

<Route path='/about/hot/detail/:id/:title' component=Detail/>

3). 参数接收

const id, title = this.props.match.params

2、传递search参数

1). 定义向路由组件传递数

<NavLink to='/about/hot/detail?id=1&title=热门001'>热门001</NavLink>

2). 无需声明接收参数

<Route path='/about/hot/detail' component=Detail/>

3). 参数接收

//引入query-string,yarn add query-string
import qs from 'query-string'
//参数接收
const search = this.props.location
const id, title = qs.parse(search.slice(1))

获取到的search是url编码的字符串,需要借助于query-string解析。

3、传递state参数-隐藏地址栏参数

1). 定义向路由组件传递数

<NavLink to=
    pathname:'/about/hot/detail',
    state:
        id:'1',
        title:'热门001'
    
>热门001</NavLink>

2). 无需声明接收参数

<Route path='/about/hot/detail' component=Detail/>`

3). 参数接收

const id, title = this.props.location.state || 

        这种方式传递参数访问地址栏没有参数,只有http://localhost:3000/#/about/hot/detail,参数存储在history,刷新可以保留参数,清空缓存之后,会引发异常,需要做非空判【 || 】。

八、push和replace模式

        路由跳转默认开始前的是push,可以使用replace开启替换模式,开启后不会留下痕迹:

<NavLink replace to='/about/hot/detail/1/热门001'>热门001</NavLink>
<NavLink replace to='/about/hot/detail/2/热门002'>热门002</NavLink>

        页面1——>热门001跳转到——>热门002,回退页面,直接显示页面1

九、命令方式触发路由跳转

        Link或者NavLink方式来实现路由需要点击才能跳转,在某些情况下不需要点击也需要跳转,例如倒计时几秒调转到某页面,这时候Link就管用了,需要使用history方式:

<button onClick=() => this.pushShow(4, '热门004')>push查看</button>
<button onClick=() => this.replaceShow(4, '热门004')>replace查看</button>

replaceShow = (id, title) => 
    //编写一段代码,实现跳转到详情页面
    this.props.history.replace(`/about/hot/detail/$id/$title`)


pushShow = (id, title) => 
    //编写一段代码,实现跳转到详情页面
    this.props.history.push(`/about/hot/detail/$id/$title`)

        这样不通过Link的方式就路由到新的页面了。这里是依params参数方举例,search方式也类似,需要注意的是state方式参数需要写在第二个参数上:

this.props.history.replace(`/about/hot/detail`,id:'4', title:'热门004')
this.props.history.push(`/about/hot/detail`,id:'4', title:'热门004')

十、命令方式触后退,前进

//前进
forward = () => 
    this.props.history.goForward()

//后退
back = () => 
    this.props.history.goBack()

//前进+后端  
go = () => 
    //前进一步
    this.props.history.go(1)
    //前进两步
    this.props.history.go(2)
    //后端一步
    this.props.history.go(-1)
    //后退两步
    this.props.history.go(-2)

十一、withRouter

        可以加工一般组件,让一般组件具有路由组件的API ,withRouter返回一个新的组件:

import React, Component from 'react';
import withRouter from 'react-router-dom'

/**
 * 一般组件
 */
class Header extends Component 

    render() 
        return (
            <div>
                React Demo
                <button onClick=() => this.forward()>前进</button>
                <button onClick=() => this.back()>后退</button>
            </div>
        );
    

    forward = () => 
        this.props.history.goForward()
    

    back = () => 
        this.props.history.goBack()
    

//暴露的是withRouter暴露组件的返回值
export default withRouter(Header)

十二、BrowserRouter和HashRouter区别

以上是关于React中的路由的主要内容,如果未能解决你的问题,请参考以下文章

十 React路由(react-router4.x): 动态路由get传值React中使用url模块

React 系列 - 写出优雅的路由

React 系列 - 写出优雅的路由

react动态路由以及获取动态路由

react路由跳转失效原因

路由跳转后跳转回来保留滚动条位置