React-Router

132 阅读3分钟

React-Router的功能包react-router | react-router-native | react-router-config | react-router-dom。

在做web端开发的时候只需要安装react-router-dom(目前5.2.0版本)就可以了,因为内部已经包含了最核心的内容了。

路由的简单使用

安装路由: yarn add react-router-dom

需要在最外层的节点上面:(hash vs history)

import {HashRouter as Router} from "react-router-dom"
ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById('root')
);

 使用Route实现路由

import React,{Component} from 'react';
import {Route,Redirect,Switch} from "react-router-dom"
import Home from "./views/Home"
import Article from "./views/Article"
import NotFound from "./views/NotFound"

//Route指代路由对象,path匹配路径,component代表路由组件  exact就是将地址栏与path必须完全一致
//Redirect重定向 to跳到指明的路径
//Switch 内部的路由只要匹配一个就结束了
class App extends Component{
  render(){
    return (
      <Switch>
        <Route path="/home" component={Home}/>
        <Route path="/article" component={Article}/>
        <Route path="/404" component={NotFound}/>
        <Redirect to="/home" from="/" exact/>   
        <Redirect to="/404"/>
      </Switch>
    )
  }
}
export default App;

声明式导航 (vue中router-link实现的)

可以通过NavLink实现a标签的切换效果,渲染成a标签(在浏览器的Elements),并且带有active的class样式

import {Route,Redirect,Switch,NavLink as Link} from "react-router-dom"

<Link to="/home" activeStyle={{color:'red'}}>首页</Link>
<Link to="/article" activeStyle={{color:'red'}}>文章</Link> 

二级路由与动态跳转

二级路由:

Article文件:

import React, { Component } from 'react'
import {Route,NavLink as Link} from "react-router-dom"
import ArticleDetail from './ArticleDetail';
export default class Article extends Component {
    render() {
        return (
            <div>
                <Link to="/article/1">文章一</Link>
                <Link to="/article/2">文章二</Link>
                <Route path="/article/:id" component={ArticleDetail}/>
            </div>
        )
    }
}

ArticleDetail中如何获取动态参数?

因为ArticleDetail被Route进行包裹,就是路由组件了。它的属性上面就会有路由相关的api

import React, { Component } from 'react'

export default class ArticleDetail extends Component {
    render() {
        //history/location/match的路由api了。
        return (
            <div>
                文章详情 -- {this.props.match.params.id}
            </div>
        )
    }
}

路由常用的api方法

Route中的render函数

 一旦通过Route组件的component属性指明的组件,那么这个路由组件上面就会有路由相关的api

(location / history / match)

如果必须要传入额外属性的话,单纯使用component是解决不了的。

<Route path="/home" render={(routeProps)=>{
	return this.state.isLogin ? <Home {...routeProps} a={1}/> : "未登录"
}}/>

link的参数传递

1.可以通过动态路由的方式进行参数传递

    path="/detail/:id"

    Detail组件内部可以通过 this.props.match.params.id可以获取到动态参数

2.可以通过query进行传参

   path="/detail?title=文章一"

   Detail组件内部可以通过 this.props.location.search可以获取到 “?title=文章一”

3.可以通过state进行隐式传参

   to={{pathname:'/detail/2',state:{title:'文章2'}}}

   Detail组件内部可以通过 this.props.location.state.title可以获取到

withRouter (HOC:React.memo() connect() withRouter)

我们可以通过引入高阶组件withRouter,将普通组件进行包裹,那么BackHome就变成了伪路由组件,它本身不能实现跳转,但是仍然可以通过属性去访问到路由相关的api了。

import React, { Component } from 'react'
import {withRouter} from "react-router-dom"

//withRouter(BackHome) 本来BackHome是一个普通组件,属性上面啥也没有。但是通过HOC withRouter包裹之后,这个BackHome就变成了一个伪路由组件,本身是不会跳转进来,只不过属性上面却有了路由相关的api。
@withRouter
class BackHome extends Component {

    back = ()=>{
        //通过编程式导航方式返回首页
        this.props.history.push("/home")
    }

    render() {
        return (
            <div>
                <button onClick={this.back}>返回home</button>
            </div>
        )
    }
}
export default BackHome

在掘金分享知识与快乐!