React 路由/5版本

本文详细介绍了如何使用React Router DOM v5进行SPA应用的路由配置,包括HashRouter和BrowserRouter的使用,Link、NavLink、Route、Switch和Redirect等组件的实践,以及编程式导航的方法。此外,还涵盖了路由参数传递(params、search和state)和嵌套路由的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

脚手架编译打包出来的是 SPA 单页面应用 所依赖的核心就是前端路由

安装:指定5版本

npm i react-router-dom@5  

一、入口文件要包裹 HashRouter / BrowserRouter

// 相当于 main.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import {HashRouter,BrowserRouter} from 'react-router-dom'
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  // React.StrictMode 标签 严格模式 检查
  <React.StrictMode>
    <HashRouter>
      <App />
    </HashRouter>
  </React.StrictMode>
);

//  页面性能分析 需要 web-vitals库的支持
reportWebVitals();

react-router-dom  一些内置组件使用的介绍:

  1. Link 路由跳转的按钮 to = '路径名'
  2. NavLink 带有高亮效果的 路由导航(添加 active类名)
  3. Route   path = 要匹配的路径  component = 对应展示的组件 exact属性 开启严格匹配
  4. Swicth  开启精准匹配 当匹配上一个路径时 显示对应组件 不再继续向下匹配
  5. Redirect  默认指向  没有匹配上时就对应这个
//import axios from 'axios';
import React, { Component } from 'react'
import './App.css';
import {NavLink,Route,Switch,Redirect} from 'react-router-dom'
import Home from './component/Home'
import About from './component/About'
import Formerly from './component/Formerly'
import Case from './page/Case'
import MyNavLink from './component/MyNavLink'
export default class App extends Component {
  render(){
      return (
          <div className="container">
              <div className="row">
      <div className="col-xs-offset-2 col-xs-8">
        <div className="page-header"><h2>React Router Demo</h2></div>
      </div>
    </div>
    <Formerly a={8755}/>
    <div className="row">
      <div className="col-xs-2 col-xs-offset-2">
        <div className="list-group">
          <NavLink className='list-group-item' to='/about'>About</NavLink>
          <NavLink className='list-group-item' to='/home'>Home</NavLink>
          <NavLink className='list-group-item' to='/case'>Case</NavLink>
          自己封装:
          <MyNavLink to="about/b/c">关于</MyNavLink>
          <MyNavLink to="home">首页</MyNavLink>
          <MyNavLink to="case" children="案例"></MyNavLink>
          模糊匹配精准匹配
        </div>
      </div>
      <div className="col-xs-6">
        <div className="panel">
          <div className="panel-body">
            <Switch>
            <Route path='/about' exact component={About}></Route>
            <Route path='/home' component={Home}></Route>
            <Route path='/case' component={Case}></Route>
            <Route path='/about'  component={Formerly}></Route>
            <Redirect to="/home"/>
            </Switch>
          </div>
        </div>
      </div>
    </div>
    Redirect写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由 <br></br>
    普通about 开启了严格匹配 Formerly没有开启 所以 about/b/c 关于 会导向 Formerly
          </div>
      )
  }
}

封装MyNavLink

相同的类名比较多时可以 自行封装一下  接收到的props 直接展开到 组件中

传入 children  就是写入标签内的数据

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

export default class index extends Component {
  render() {
    return (
      <NavLink {...this.props} className="list-group-item"></NavLink>
    )
  }
}

路由组件与一般组件

1.写法不同 引用方式不同

            一般组件:<Demo/> 手动固定引入

            路由组件:<Route path="/demo" component={Demo}/>  用到时再加载

2.接收到的props不同: 

            一般组件:写组件标签时传递了什么,就能收到什么

            路由组件:接收到三个固定的属性 history location match

嵌套路由:

1.注册子路由时要写上父路由的path值

2.路由的匹配是按照注册路由的顺序进行的

这里以 Case组件为例

import React, { Component } from 'react'
import New from './New'
import Message from './Message'
import { Link,Route } from 'react-router-dom'

export default class Case extends Component {
  render() {
    //console.log('路由组件会有默认props',this.props,'这里也执行了两次?')
    return (
      <div>
        <h3>
          Case组件是保存在 page里的路由组件
          <br />
          这里显示的是嵌套路由
        </h3>
      <Link to='/case/new'>新闻</Link>
      <Link to='/case/message'>消息</Link>
      <Route path="/case/new" component={New}></Route>
      <Route path="/case/message" component={Message}></Route>
      </div>
    )
  }
}

路由传递参数

1.params 传参 

路径跳转时直接写上 数据 / 分割 

<Link to={`/case/new/detail/947/美食`}>美食</Link>

匹配展示时 要接上占位符 :标识

<Route path="/case/new/detail/:id/:title" component={Detail}></Route>

在跳转的组件内部  this.props.match.params 解构出来 使用

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

2.search 传参

相当于url中的query字符串 ?开始 &分隔

<Link to={`/case/new/detail?id=857&title=汽车`}>汽车</Link> 

匹配展示时不用添加参数

 <Route path="/case/new/detail" component={Detail}></Route>

接收 search 参数 在 this.props.location 里 但它是查询字符转  想用要转化成对象

const {search} = this.props.location

3.state传参

单独写对象 pathname 路径名  state传递的参数分开

<Link to={{pathname:'/case/new/detail',state:{id:666,title:娱乐}}}>娱乐</Link> 

匹配展示时不用添加参数

 <Route path="/case/new/detail" component={Detail}></Route>

接收 state 参数 在 this.props.location 里 它不会显示在地址栏

const {id,title} = this.props.location.state

完整代码:

Case/New

import React, { Component } from 'react'
import { Link,Route } from 'react-router-dom'
import Detail from './Detail'

export default class New extends Component {
  state={
    NewArr:[
      {id:"101",title:'新闻1'},
      {id:"201",title:'新闻2'},
      {id:"301",title:'新闻3'}
    ]
  }

  pushS = (id,title) =>{
    // push跳转 携带 state参数
    this.props.history.push('/case/new/detail',{id,title})

    // search
    //this.props.history.push(`/case/new/detail?id=${id}&title=${title}`)

    // params
        //this.props.history.push(`/case/new/detail/${id}/${title}`)
  }

  replaceS = (id,title) => {
    // replace跳转 携带 state参数
    this.props.history.replace('/case/new/detail',{id,title})

    // search
    //this.props.history.replace(`/case/new/detail?id=${id}&title=${title}`)

    // params
        //this.props.history.push(`/case/new/detail/${id}/${title}`)
  }




  render() {
    const {NewArr} = this.state
    return (
      <div>
        <ul>
          {
            NewArr.map((x) =>{
              return (
                    <li key={x.id}>
                      {/**
                       * 向组件传递 params 参数
                       * <Link to={`/case/new/detail/${x.id}/${x.title}`}>{x.title}</Link>
                       * 向组件传递 search 参数
                       *  <Link to={`/case/new/detail?id=${x.id}&title=${x.title}`}>{x.title}</Link> 
                       *  state
                       * 
                       */}
                      <Link to={{pathname:'/case/new/detail',state:{id:x.id,title:x.title}}}>{x.title}</Link> 
                      <button onClick={() => this.pushS(x.id,x.title)}>push编程跳转路由</button>       
                      <button onClick={() => this.replaceS(x.id,x.title)}>replace编程跳转路由</button>    
              </li> 
              )
            })
          }
        </ul>

        <hr />
        {/** 声明接收 params 参数
         * <Route path="/case/new/detail/:id/:title" component={Detail}></Route>
         * search 参数无需声明接收 正常注册路由即可
         * state 参数无需声明接收 正常注册路由即可
         * 
         */}
          <Route path="/case/new/detail" component={Detail}></Route>
      </div>
    )
  }
}

 Detail:

import React, { Component } from 'react'
//import qs from 'querystring'

const DetailData = [
  {id:"101",context:'鼎立中原'},
  {id:"201",context:'哑铃战术'},
  {id:"301",context:'西南追歼'},
]

export default class Detail extends Component {
  render() {
    console.log(this.props)

    // 接收params 参数
   // const {id,title} = this.props.match.params
  
    // 接收 search 参数
     // const {search} = this.props.location
     // const {id,title} = qs.parse(search.slice(1))

    // 接收 state 参数
    const {id,title} = this.props.location.state

    const findRes = DetailData.find(x =>{
      return x.id === id
    })
    return (
      <ul>
        <li>ID:{id}</li>
        <li>TITLE:{title}</li>
        <li>{JSON.stringify(findRes)}</li>
      </ul>
    )
  }
}

编程式路由

之前都是通过 Link  NavLink 来实现跳转 这是声明式导航

也可以利用API实现 编程式导航

使用场景:满足条件自动跳转、定时器事件满后自动跳转......

  • this.props.history.push() push 跳转(压栈)有记录
  • this.props.history.replace() replace 跳转 直接替换

  • this.props.history.goBack() 退后一步

  • this.props.history.goForward() 前进一步

  • this.props.history.go() 填写数字 正数前进 负数退后

 也可以 携带 三种参数

  pushS = (id,title) =>{
    // push跳转 携带 state参数
    this.props.history.push('/case/new/detail',{id,title})

    // search
    //this.props.history.push(`/case/new/detail?id=${id}&title=${title}`)

    // params
        //this.props.history.push(`/case/new/detail/${id}/${title}`)
  }

  replaceS = (id,title) => {
    // replace跳转 携带 state参数
    this.props.history.replace('/case/new/detail',{id,title})

    // search
    //this.props.history.replace(`/case/new/detail?id=${id}&title=${title}`)

    // params
        //this.props.history.push(`/case/new/detail/${id}/${title}`)
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值