React-router5.x 路由的使用

路由器组件(<BrowserRouter>、<HashRouter>)
路由匹配组件(<Route>、<Switch>)
导航组件(<Link>、<NavLink>)。

路由组件 BrowserRouter 和 HashRouter

BrowserRouter(history模式) 和 HashRouter(hash模式)作为路由配置的最外层容器,是两种不同的模式,可根据需要选择。

hash模式:

class App extends React.Component{
  render(){
    return (//映射路由
      <HashRouter>
          <Route exact path="/public" component={Public}/>
          <Route exact path="/login" component={Login}/>
          <Route exact path="/home" component={Home}/>
          <Redirect exact from='/' to="/public" />
      </HashRouter>
    );
  }
}

项目运行结果:

props:

{
  "history": {
    "length": 5,
    "action": "REPLACE",
    "location": "{hash: \"\", pathname: \"/public\", search: \"\", state: …}",
    "createHref": "createHref",
    "push": "push",
    "replace": "replace",
    "go": "go",
    "goBack": "goBack",
    "goForward": "goForward",
    "block": "block",
    "listen": "listen"
  },
  "location": {
    "pathname": "/public",
    "search": "",
    "hash": ""
  },
  "match": {
    "path": "/public",
    "url": "/public",
    "isExact": true,
    "params": "{}"
  }
}

history模式:

class App extends React.Component{
  render(){
    return (//映射路由
      <BrowserRouter>
          <Route exact path="/public" component={Public}/>
          <Route exact path="/login" component={Login}/>
          <Route exact path="/home" component={Home}/>
          <Redirect exact from='/' to="/public" />
      </BrowserRouter>
    );
  }
}

运行结果:

props:

{
  "history": {
    "length": 5,
    "action": "REPLACE",
    "location": "{hash: \"\", key: \"iu0aod\", pathname: \"/public\", sear…}",
    "createHref": "createHref",
    "push": "push",
    "replace": "replace",
    "go": "go",
    "goBack": "goBack",
    "goForward": "goForward",
    "block": "block",
    "listen": "listen"
  },
  "location": {
    "pathname": "/public",
    "search": "",
    "hash": "",
    "key": "iu0aod"
  },
  "match": {
    "path": "/public",
    "url": "/public",
    "isExact": true,
    "params": "{}"
  }
}

以上是使用history与hash模式的结果整理,从控制台输出props中发现使用history比hash模式在location对象中多了一个key属性,以及url中hash模式多了#。暂且还未发现什么不同,如后续深究会在更新~

路由匹配组件:Route,Switch

Route:用来控制路径对应显示的组件,有以下几个参数:

path:指定路由跳转路径

exact:精确匹配路由

componnet:路由对应的组件

import Home from "./pages/Home/Home";
......

<Route exact path="/home" component={Home}/>
    

render: 通过写render函数返回具体的dom:

<Route path='/home' exact render={() => (<div>home</div>)}></Route>

结果图

render 也可以直接返回 Home组件,像下面:

<Route path='/home' exact render={() => <Home/>}></Route>

也可以通过 render 方法传递 props 属性,并且可以传递自定义属性:

 <Route path='/home' exact render={(props) => {
          return <Home {...props} name={'Ali'}/>
  }}/>

然后,就可在 Home组件中获取 props 和 name 属性:

import React from 'react'

class  Home extends React.Component{
  state={
    name:''
  }
  componentDidMount() {
    var name = this.props.name
    this.setState({name})
  }
  render() {
    return(
      <h1>{this.state.name}</h1>
    )
  }
}
export default Home;

render 方法也可用来进行权限认证:

<Route path='/home' exact render={(props) => {
    // isLogin 从 redux 中拿到, 判断用户是否登录
    return isLogin ? <User {...props} name={'Ali'} /> : <div>请先登录</div>
}}/>

location: 将 与当前历史记录位置以外的位置相匹配,则此功能在路由过渡动效中非常有用

sensitive:是否区分路由大小写

strict: 是否配置路由后面的 '/'

Switch

渲染与该地址匹配的第一个子节点 <Route> 或者 <Redirect>,类似于选项卡,只是匹配到第一个路由后,就不再继续匹配:

<Switch>
   <Route path="/public" component={Public}/>
   <Route path="/login" component={Login}/>
   <Route path="/home" component={Home}/>
   <Redirect from='/' to="/public" />
</Switch>

//类似于:
//switch(Route.path){
//  case '/home':
//       return Home
//  case '/login': 
//       return Login
//  default:
//       return Pulic     
//}

 

如果路由 Route 外部包裹 Switch 时,路由匹配到对应的组件后,就不会继续渲染其他组件了。但是如果外部不包裹 Switch 时,所有路由组件会先渲染一遍,然后选择到匹配的路由进行显示。

导航组件:Link,NavLink

Link 和 NavLink 都可以用来指定路由跳转,NavLink 的可选参数更多。

两种配置方式:

通过字符串执行跳转路由

<Link to="/login" >登录</Link>

通过对象指定跳转路由

  • pathname: 表示要链接到的路径的字符串。
  • search: 表示查询参数的字符串形式。
  • hash: 放入网址的 hash,例如 #a-hash。
  • state: 状态持续到 location。通常用于隐式传参(埋点),可以用来统计页面来源
<Link to={{
            pathname: '/login',
            search: '?name=aaa',
            hash: '#someHash',
            state: { fromWechat: true }
          }}>
    登录
</Link>

可以看做 一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。

<NavLink
  to="/login"
  activeStyle={{
    fontWeight: 'bold',
    color: 'red'
   }}
>
    <span>登录</span>
</NavLink>
  • exact: 如果为 true,则仅在位置完全匹配时才应用 active 的类/样式。
  • strict: 当为 true,要考虑位置是否匹配当前的URL时,pathname 尾部的斜线要考虑在内。
  • location 接收一个location对象,当url满足这个对象的条件才会跳转
  • isActive: 接收一个回调函数,只有当 active 状态变化时才能触发,如果返回false则跳转失败
const oddEvent = (match, location) => {
  if (!match) {
    return false
  }
  const eventID = parseInt(match.params.eventID)
  return !isNaN(eventID) && eventID % 2 === 1
}
 
<NavLink
  to="/login"
  isActive={oddEvent}
>login</NavLink>

Redirect:即用户访问一个路由,会自动跳转到另一个路由。

<Redirect  from='/' to="/public" />

上面,当访问路由 '/'时会直接重定向到 '/public'

<Redirect> 常用在用户是否登录:

class Center extends PureComponent {
    render() {
        const { loginStatus } = this.props;
        if (loginStatus) {
            return (
                <div>个人中心</div>
            )
        } else {
            return <Redirect to='/login' />
        }
    }
}

也可使用对象形式:

<Redirect
  to={{
    pathname: "/login",
    search: "?name=Ali",
    state: { referrer: currentLocation }
  }}
/>

withRouter

withRouter 可以将一个非路由组件包裹为路由组件,使这个非路由组件也能访问到当前路由的match, location, history对象。

import { withRouter } from 'react-router-dom';
 
class Detail extends Component {
    render() {
        ··· ···
    } 
}
 
const mapStateToProps = (state) => {
    return {
        ··· ···
    }
}
 
const mapDispatchToProps = (dispatch) => {
    return {
        ··· ···
    }
}
 
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));

注意:只有通过 Route 组件渲染的组件,才能在 this.props 上找到history对象。

编程式导航 - history 对象

例如,点击img进入登录页:

class Home extends PureComponent {
 
    goHome = () => {
        console.log(this.props);
        
        this.props.history.push({
            pathname: '/login',
            state: {
                identityId: 1
            }
        })
    }
 
    render() {
        return (
            <img className='banner-img' alt='' src="img.png" onClick={this.goHome} />
        )
    } 
}

所以,如果想在路由组件的子组件中使用 history ,需要使用 withRouter 包裹:

import React, { PureComponent } from 'react';
import { withRouter } from 'react-router-dom';
 
class 子组件 extends PureComponent {
 
    goHome = () => {
        this.props.history.push('/home')
    }
 
 
    render() {
        console.log(this.props)
        return (
            <div onClick={this.goHome}>子组件</div>
        )
    }
}
 
export default withRouter(子组件);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值