React-Route路由

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-05-26

基本使用

// 安装4.x版本的 react-route-dom 是包含了核心库 react-route的
// npm i react-route-dom  -S

// import { Router }  from 'react-route-dom'

// 这个Router是相当于是VueRouter的,负责包括所有的路由记录
// 但是本身是抽象的 不能直接使用 因为它不知道该使用哪种模式

// 它拥有四个子类:{BroswerRouter} {HashRouter} {StaticRouter} {MemoryRouter}

// BroswerRouter  对应 history模式
// HashRouter 对应  hash 模式

import { BrowserRouter as Router, Route } from 'react-router-dom'

class App extends React.Component {
  render() {
    return (
      <Router>
        <div>
          { /* exact 精准拼配 Router必须有一个根元素 */ }
          <Route exact path="/" component={ Home } />
          <Route path="/news" render={()=>(<h1>我是一个news组件</h1>)} />
        </div>
      </Router>
    )
  }
}

ReactDOM.render(<App/>, document.getElementById('app'))

关于重定向

import { HashRouter as Router,Route,Redirect } from 'react-router-dom'

<Router>
  <div>
    <Route path="/goods" component={Goods}/>
    <Redirect to="/home" from="/" /> {/* /重定向到首页 */}
  </div>
</Router>

<Route exact path="/" render={() => (
  loggedIn ? (<Redirect to="/dashboard"/>) : (<PublicHomePage/>)
)}/>

<Redirect
  to={{
    pathname: "/login",
    search: "?utm=your+face",
    state: { referrer: currentLocation }
  }}
/>

<Redirect push to="/somewhere/else" />
// push 是一个bool值,使用push而不是replace
import { HashRouter as Router,Route,Link, NavLink} from 'react-router-dom'
 
<Router>
  <div>
    {/* Link标签本质还是a便签 */}
    <Link to="/home">首页</Link>
    <Link to="/goods">商品</Link>
    <hr/>

    {/* 与route-link 差不多 会给激活的NavLink 添加一个active类 */}
    <NavLink to="/home">首页</NavLink>
    <hr/>

    {/* 可以使用activeClassName自定义这个类名 一般使用第三方样式的时候使用 */}
    <NavLink to="/home" activeClassName='myActive'>首页</NavLink>
    <hr/>

    {/* 也要加exact精准匹配 不然active类会在跳转到/home的时候 在两个NavLink标签上都加上 */}
    <NavLink to="/" exact >Index</NavLink>
    <NavLink to="/home">首页</NavLink>
    <hr/>

    <Route path="/goods" component={Goods}/>
    {/* /重定向到首页 */}
    <Redirect to="/home" from="/" /> 
  </div>
</Router>

关于Switch组件

Switch组件让路由在匹配到第一个组件时就结束匹配

import { HashRouter as Router,Route,Switch} from 'react-router-dom'

<Router>
  <div>
    {/*Switch一定要加 不然有多少个路由 每次跳转的时候就会匹配多少次 影响性能*/}
    <Switch>
      {/*在Switch中 如果默认路径不加 exact 不管跳转哪里都会跳转到Index 因为'/xxx'都会匹配到'/' */}

      {/* exact是bool值 可以设置为false。exact={false} 实现的是 url.pathname === Route的path属性 */}

      <Route exact path="/" component={Index}/>
      <Route path="/home" component={Home}/>
      <Route path="/goods" component={Goods}/>
    </Switch>
  </div>
</Router>

嵌套路由

class App extends React.Component {
  render (){
    return (
      <Router>
        <Route path="/home" component={Home}/>
        <Route path="/goods" component={Goods}/>
      </Router>
    )
  }
}

class Goods extends React.Component {
  render(){
    return (
      <Router>
        {/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
        {/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods */}
        {/* 那Goods组件都不会渲染 更不会有子路由组件渲染的机会 */}
        <Route path="/goods/phone" component={Phone}/>
        <Route path="/goods/food" component={Food}/>
      </Router>
    )
  }
}

动态路由

class App extends React.Component {
  render(){
    return (
      <Router>
        <Route path="/home" component={Home}/>
        <Route path="/goods/:myPath" component={Product}/>
      </Router>
    )
  }
}

class Product extends React.Component {
  render(){
    return (
      <Router>
        <Route path="/goods/phone" component={Phone}/>
        <Route path="/goods/food" component={Food}/>
      </Router>
    )
  }

  componentDidMount(){ // 一般在这个钩子中请求数据 渲染视图
    console.log(this.props)
    // 动态路由的props上有三个属性 history location match

    // history 历史对象 == this.props.history.push() /  this.props.history.replace() / goBack / go
    // 编程式跳转

    // location 当前地址信息对象 = 当前路由的 hash pathname search(?a=1&b=2) state 

    // match 匹配对象 拥有isExact  params:{myPath:phone}  path: '/:myPath' url: '/phone'
  }
}

为什么要在componentDidMount中获取数据:更新期4个钩子不能调用setState 所有创建周期的render不行,然后componentWillMount会被执行两次

动态路由需要在componentWillReceiveProps获取数据,因为动态路由使用同一个组件,组件的componentDidMount只会执行一次。