react 路由的几种使用方式

React Router包含了四个包

包名Description
react-routerReact Router核心api
react-router-domReact Router的DOM绑定,在浏览器中运行不需要额外安装react-router
react-router-nativeReact Native 中使用,而实际的应用中,其实不会使用这个。
react-router-config静态路由的配置

主要使用`react-router-dom

1.声明式路由

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, NavLink} from 'react-router-dom'
import './style.css'

const Home = () => <div>首页</div>
const Kind = () => <div>分类</div>
const Cart = () => <div>购物车</div>
const User = () => <div>我的</div>

export default class App extends Component {
  render() {
    // children  --- 所有的路由都会渲染该路由对应的组件 
    // React路由声明式跳转 Link  NavLink
    return (
      <Router>
        <ul>
          <li><NavLink activeClassName="selected" to="/home">首页</NavLink></li>
          <li><NavLink activeClassName="selected" to="/kind">分类</NavLink></li>
          <li><NavLink activeClassName="selected" to="/cart">购物车</NavLink></li>
          <li><NavLink activeClassName="selected" to="/user">我的</NavLink></li>
        </ul>
        <hr />
        //渲染组件的方式
        <Route path="/home" component = { Home } />
        <Route path="/kind" ><Kind /></Route>
        <Route path="/cart" render = { () => <Cart/> }></Route>
        <Route path="/user" component = { User } />
        {/* <Route path="/user" children = { () => <User/> }></Route> */}
      </Router>
    )
  }
}

2.编程式路由

...
// 编程式导航需要 使用 this.props.history 对象
// 如果当前组件没有的话,可以引入 withRouter --- 高阶组件
@withRouter
class App extends Component {
  state = { 
    currentIndex: 0
  }
  changePage = (path, index) => {
    return (e) => {
      this.setState({ currentIndex: index })
      this.props.history.push(path)
    }
  }
  render() {
    const { currentIndex } = this.state
    // 编程式跳转
    return (
      <>
        <ul>
          <li className={ currentIndex === 0 ? 'active' : ''} onClick={ this.changePage('/home', 0) }>首页</li>
          <li className={ currentIndex === 1 ? 'active' : ''} onClick={ this.changePage('/kind', 1) }>分类</li>
          <li className={ currentIndex === 2 ? 'active' : ''} onClick={ this.changePage('/cart', 2) }>购物车</li>
          <li className={ currentIndex === 3 ? 'active' : ''} onClick={ this.changePage('/user', 3) }>我的</li>
        </ul>
        ...
      </>
    )
  }
}

3.动态路由(路由传参)

const Child = (props) => {
  console.log(props)//路由参数
  const type = props.match.params.type
  return (
    <div>
      child - { type }
    </div>
  )
}

class App extends Component {
  render() {
    return (
      <>
        ...
        <Route path="/:type" component = { Child } />
      </>
    )
  }
}

4.二级路由

import React, { Component } from 'react'
import { Route, NavLink, useRouteMatch } from 'react-router-dom'
import './style.css'
// 嵌套路由
// 分类下的 导航组件
const Phone = () => <div>手机</div>
const Wash = () => <div>洗衣机</div>
const Ice = () => <div>电冰箱</div>

// 默认的导航组件
const Home = () => <div>首页</div>
const Cart = () => <div>购物车</div>
const User = () => <div>我的</div>
const Kind = () => {
  console.log(useRouteMatch())
  const { url } = useRouteMatch() // useRouteMatch只能在函数式组件中使用
  return (
    <div>
      分类
      <ul>
        <li><NavLink to={ `${ url }/phone`}>大哥大</NavLink></li>
        <li><NavLink to={ `${ url }/wash`}>洗衣机</NavLink></li>
        <li><NavLink to={ `${ url }/ice`}>电冰箱</NavLink></li>
      </ul>
      <hr />
      <Route path={ `${ url }/phone`} component = { Phone } />
      <Route path={ `${ url }/wash`} component = { Wash } />
      <Route path={ `${ url }/ice`} component = { Ice } />
    </div>
  )
}
class App extends Component {
  render() {
    return (
     ...
    )
  }
}

5.路由的重定向及精纯匹配

import { Route, NavLink, useRouteMatch, Redirect, Switch, withRouter } from 'react-router-dom'

...

@withRouter
class App extends Component {
  render() {
    const pathname = '/' + this.props.location.pathname.split('/')[1]
    return (
      <>
        ...
        
        {/* Switch 只能选择其中一个路由 */}
        <Switch >
          <Route path="/home" component = { Home } />
          <Route path="/kind" component = { Kind } />
          <Route path="/cart" component = { Cart } />
          <Route path="/user" component = { User } />
          {/* exact 精准匹配 只有当路由为 / 时,才会重定向 */}
          <Redirect path="/" exact to="/home" />
          {/* 404路由配置在最底下 */}
          <Route path="*" component = { NoMatch } />
        </Switch>
      </>
    )
  }
}

6.组件的递归调用

import React from 'react'
import { Switch, Route, Link, Redirect, useParams, useRouteMatch} from 'react-router-dom'
// 组件的递归调用 --- 不常见
const list = [
  { id: 0, name: '张三', friends: [1, 2]},
  { id: 1, name: '李四', friends: [0, 2]},
  { id: 2, name: '王五', friends: [0, 1, 3]},
  { id: 3, name: '麻六', friends: [0]}
]

const find = (id) => {
  return list.find( item => item.id === id)
}
const Person = (props) => {
  const { url } = useRouteMatch() // this.props.match
  // console.log(url)
  const { id } = useParams() // this.props.match.params
  const person = find(id*1)
  return (
    <>
      { person.name } 的朋友有:
      <ul>
        {
          person.friends.map((id, index) => {
            let per = find(id*1)
            return (
              <li key = { index }>
                <Link to={ `${url}/${ id }`}>
                  { per.name }
                </Link>
              </li>
            )
          })
        }
      </ul>
      {/* 形成了组件的递归调用 */}
      <Route path={ `${url}/:id`} component={Person}/>
    </>
  )
}
const App = () => {
  return (
    <Switch>
      <Route path='/:id' component={Person}/>
      <Redirect path="/" exact to="/0" />
    </Switch>
  )
}

export default App
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值