React路由
创始人
2024-03-02 17:27:30
0

文章目录

  • 单页面应用spa
  • 路由
    • 路由是什么
    • React路由原理
      • 点击页面选项路径改变
      • 路径改变页面变化
    • React路由的使用
      • 实现点击页面选项路径改变——编写路由链接
      • 根据路径显示组件 ——注册路由
      • 组件的分类——普通组件和路由组件
      • 案例
      • 实现选中高亮效果——NavLink
      • NavLink的封装
      • Switch的使用
      • 补充:样式丢失问题
        • 解决·:
      • 路由的严格匹配与模糊匹配
        • 模糊匹配
        • 严格匹配
    • Redirect重定向的使用
    • 嵌套路由
    • 路由传参
      • 向路由组件传递params参数
        • 使用方法
        • 例子
      • 向路由组件传递search参数(query参数)
        • 补充:qs库
        • 使用方式
        • 例子
      • 向路由组件传递state参数
        • 使用方式
        • 例子
    • 路由的两种模式push与replace
    • 编程式路由导航
    • withRouter的使用(一般组件实现编程式路由导航)
    • BrowserRouter 和 HashRouter的区别

单页面应用spa

多页面应用是指每切换一个页面就是一个真正的html页面。
单页面应用是指整个应用只有一个完整的页面,点击页面中的链接不会刷新页面只会局部更新,并且数据都需要通过ajax请求获取,并在前端异步展示。

单页面,多组件。

路由

路由是什么

  1. 什么是路由? —— Route
    —个路由就是一个映射关系 ( key:value )
    key为路径, value 可能是function(后端路由)或component(前端路由)路由分类
  • 后端路由:
    理解:value是function,用来处理客户端提交的请求。
    注册路由: router.get(path, function(req, res))
    工作过程:当node接收到一个请求时,根据请求路径找到匹配的路由,调用路
    由中的函数来处理请求返回响应数据
  • 前端路由:
    浏览器端路由,value是component,用于展示页面内容。
    注册路由:
    工作过程:当浏览器的path变为/test时,当前路由组件就会变为Test组件
  1. 路由器 —— Router
    路由器是用于管理路由的。

React路由原理

在这里插入图片描述
路由匹配的是只是端口号后面的内容(/about、/history)。

点击页面选项路径改变

那么是如何实现一点击导航栏的选项浏览器地址栏中的路径就改变呢, 这就需要借助history实现。
浏览器的BOM身上有一个history,用于管理浏览器的路径、历史记录等。
但是BOM原生的history不好操作我们一般用一个封装好的库history.js,(该库实际上操作的也是BOM身上的history)引入:


,使用:

  1. 引入:
let history = History.createBrowserHistory()
  1. 推入
// 将路径放到历史记录history中history.push(path)
  1. 替换
// 将路径放到历史记录history中history.replace(path)
  1. 监听路径变化
// history的listen方法可以监听路径的修改history.listen((location) => {console.log('请求路由路径变化了', location)})
  1. 前进
	history.goForward()
  1. 后退
	history.goBack()

history的数据结构是栈结构:
在这里插入图片描述
栈顶的路径就是当前页面显示的内容。

History.createBrowserHistory()是使用的是h5身上的history方法,在某些旧的浏览器不支持。
可以使用: History.createHashHistory(),和createBrowserHistory的区别是路径中会多出一个 # ,虽然不好看但是兼容性特别好。

History.createBrowserHistory():

在这里插入图片描述

History.createHashHistory():

在这里插入图片描述

路径改变页面变化

React会监听路径,当路径发生变化时,被前端路由器检测到,就会进行路由匹配重新渲染页面。

React路由的使用

React路由的实现需要借助react的路由插件库:react-router-dom, 专门用于实现SPA应用。

  • 安装:
npm i react-router-dom

实现点击页面选项路径改变——编写路由链接

直接利用从 react-router-dom 库中引入的路由器Router标签就可以实现:

import { BrowserRouter, Link } from 'react-router-dom'AboutHome

点击About浏览器的路径就变成 /about, 点击Home浏览器的路径就变成/home

有两种Router标签:,在Router标签中再使用进行路由。
标签就对应history的browser模式
标签就对应history的hash模式

(最后在浏览器渲染的时候,Link标签实际上是会转换为a标签的)

根据路径显示组件 ——注册路由

直接利用从 react-router-dom 库中引入的路由Route 进行路由的注册:

   import { Route } from 'react-router-dom'
{/* 注册路由 */}About}/>Home}/>

也需要使用Router标签进行包裹,但是编写路由链接的路由器应该和注册路由的路由器是一个路由器才对,可以直接将组件使用Router标签包裹即可。

index.js

// 引入react核心库
import React from 'react'
// 引入ReactDOM
import ReactDOM from 'react-dom'
// 引入路由组件
import { BrowserRouter } from 'react-router-dom'
// 引入App组件
import App from './App'// 渲染App到页面
ReactDOM.render(, document.getElementById('root'))

组件的分类——普通组件和路由组件

像上面的例子通过路由来使用组件:,这样的组件叫做路由组件。还有一类就是通过标签正常使用的组件如,这样的组件就是普通组件。
普通组件一般直接放在src/component文件夹中,路由组件一般放在src/pages中。

普通组件和路由组件一个最大的区别就是,路由组件可以接收到路由器传递的参数。如当点击上述例子的About按钮时,接收到的参数为:
在这里插入图片描述

  • history :
    go:可以穿参数n,表示前进或后退|n|步,n>0表示前进n步,n<0表示后退n步。
    goBack:后退1步
    goForward:前进1步
    push:push路由
    replace:replace路由
    location:(和下面的这个location是同一个对象)
  • location
    pathname:获取路由路径
    search:(存储swarch参数)
    state:(存储state参数)
  • match
    params:(存储params参数)
    path:获取路由路径
    url:获取路由路径

案例

实现效果:
在这里插入图片描述
在这里插入图片描述
代码:

在这里插入图片描述
src/index.js

// 引入react核心库
import React from 'react'
// 引入ReactDOM
import ReactDOM from 'react-dom'
// 引入路由组件
import { BrowserRouter } from 'react-router-dom'
// 引入App组件
import App from './App'// 渲染App到页面
ReactDOM.render(, document.getElementById('root'))

src/App.jsx

import React, { Component } from 'react'
import {  Link, Route } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
export default class App extends Component {render() {return (
{/* 原生直接使用a标签进行切换 */}{/* AboutHome */}{/* react中靠路由链接进行切换 */}{/* 有两种Router:再Router标签中再使用Link进行路由*/}AboutHome
{/* 注册路由 */}About}/>Home}/>
)} }

page/About/index.jsx

import React, { Component } from 'react'export default class About extends Component {render() {console.log("接收到参数:", this.props);return (
About ...
)} }

page/Home/index.jsx

import React, { Component } from 'react'export default class Home extends Component {render() {return (
Home ...
)} }

components/Header/index.jsx

import React, { Component } from 'react'export default class index extends Component {render() {return (

React Router Demo

)} }

实现选中高亮效果——NavLink

需要借助 实现, 标签配合 activeClassName='类名' 实现,当点击该标签 该样式就会显示。

activeClassName='类名'中的类名默认是active。
eg:
上述案例修改App.jsx

import React, { Component } from 'react'
import {  NavLink, Route } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
export default class App extends Component {render() {return (
AboutHome
{/* 注册路由 */}About}/>Home}/>
)} }

效果:
在这里插入图片描述
注意:这里我在public文件夹中已经引入了bootstrap.css样式,所以会有样式效果

NavLink的封装

知识点:

  • 组件标签的标签体中的内容会作为children属性传递给组件
  • 在组件中通过children属性就可以指定标签体的内容。

即:
App.jsx

import React, { Component } from 'react'
import { Route } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
import MyNavLink from './components/MyNavLink'
export default class App extends Component {render() {return (
{/* 标签体中的内容会作为children属性传递给组件 */}HomeAbout
{/* 注册路由 */}About}/>Home}/>
)} }

MyNavLink,jsx

import React, { Component } from 'react'
import {  NavLink } from 'react-router-dom'export default class MyNavLink extends Component {render() {return (...this.props}/>)}
}

Switch的使用

一般情况下一个路径(path)只对应一个组件,如果一个路径对应多个组件会是什么效果呢,答案是多个组件都会显示,如:

{/* 注册路由 */}About}/>Home}/>Test}/>

显示如下:
在这里插入图片描述
说明当路径匹配完成之后如果再出现同样的路径就会再次匹配,但是一般情况下一个路径对应一个组件就可以了,所以说为了提升效率,我们希望当匹配到一个路径之后,再碰到该路径就不会进行匹配了。这就可以借助组件,用组件包裹路由。

import { Route, Switch } from 'react-router-dom'
{/* 注册路由 */}About}/>Home}/>Test}/>

补充:样式丢失问题

启动React脚手架,浏览器访问http://localhost:3000/favicon.ico,代表访问public文件夹下的favicon.ico资源。即本地服务器的根路径就是/public文件夹,如果/public文件夹中没有对应的资源就会返回/public/index.html内容。

当路由路径是多级路径,并且刷新页面的时候就会出现样式丢失。因为他会把一级路由放在请求路径进行请求。
eg:
app.jsx

import React, { Component } from 'react'
import { Route, Switch } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
import MyNavLink from './components/MyNavLink'
export default class App extends Component {render() {return (
{/* 标签体中的内容会作为children属性传递给组件 */}HomeAbout
{/* 注册路由 */}About}/>Home}/>
)} }

浏览器:
在这里插入图片描述

解决·:

  • 法一: index.html中引入样式的时候使用相对路径:

  • 法二: 使用 %PUBLIC_URL%%PUBLIC_URL% 代表的是public文件夹的绝对路径

  • 法三:使用HashRouter而不是BrowserRouter。
    index.jsx
// 引入react核心库
import React from 'react'
// 引入ReactDOM
import ReactDOM from 'react-dom'
// 引入路由组件
import { HashRouter } from 'react-router-dom'
// 引入App组件
import App from './App'// 渲染App到页面
ReactDOM.render(, document.getElementById('root'))

路由的严格匹配与模糊匹配

模糊匹配

一般情况下:NavLinkto 属性和Routepath属性匹配到的路径是一样的。
NavLinkto 属性是多级路由,但是Routepath只是匹配到第一级路由,那么组件会进行展示;
但是如果当 NavLinkto 属性是一级路由,但是Routepath匹配的是多级路由,组件是不会进行展示的。
这就是模糊匹配。

eg:

import React, { Component } from 'react'
import { Route, Switch } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
import MyNavLink from './components/MyNavLink'
export default class App extends Component {render() {return (
{/* 标签体中的内容会作为children属性传递给组件 */}HomeAbout
{/* 注册路由 */}Home}/>About}/>
)} }

组件正常显示:
在这里插入图片描述
但是如果是:

import React, { Component } from 'react'
import { Route, Switch } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
import MyNavLink from './components/MyNavLink'
export default class App extends Component {render() {return (
{/* 标签体中的内容会作为children属性传递给组件 */}HomeAbout
{/* 注册路由 */}Home}/>About}/>
)} }

在这里插入图片描述
组件就不展示了。

严格匹配

就是NavLinkto 属性和Routepath属性匹配到的路径必须是一样的。
开启严格匹配的方式:给 标签添加 exact 属性。

import React, { Component } from 'react'
import { Route, Switch } from 'react-router-dom'import About from './pages/About'
import Home from './pages/Home'
import Header from "./components/Header"
import MyNavLink from './components/MyNavLink'
export default class App extends Component {render() {return (
{/* 标签体中的内容会作为children属性传递给组件 */}HomeAbout
{/* 注册路由 */}true} path="/home/a/b" component={Home}/>true} path="/about/c/d" component={About}/>
)} }

严格匹配不要随便开启,可能会导致二级路由无法使用。

Redirect重定向的使用

当Route指明的所有路由都匹配不上的时候,就匹配Redirect中的路由
使用:Redirect在所有Route标签之后使用,利用to属性指明路由地址。

  
{/* 注册路由 */}Home}/>About}/>

嵌套路由

嵌套路由就是在路由组件中再进行路由的导航和注册。
eg:效果:
在这里插入图片描述
新增和改动的页面:
Home/index.jsx

import React, { Component } from 'react'
import {Switch, Route, Redirect} from 'react-router-dom'import MyNavLink from '../../components/MyNavLink'
import News  from './News'
import Message from './Message'export default class Home extends Component {render() {return (

我是Home组件

  • News
  • Message
{/* 注册路由 */}News}/>Message}/>
)} }

Home/News/index.jsx

import React, { Component } from 'react'export default class News extends Component {render() {return (
  • news001
  • news002
  • news003
)} }

Home/Message/index.jsx

import React, { Component } from 'react'export default class Message extends Component {render() {return ()}
}

Home/index.js中的 News匹配的路由就是二级路由,注意这里的路由匹配规则不是直接匹配。所有的路由匹配会按照注册路由的顺序进行匹配, News会先匹配App.jsx中的注册路由,匹配到了之后再去Home组件匹配注册路由,当匹配到了就在页面进行显示 。

Home/index.js中的, 就是设置当只匹配到了/home, 后面的路径未匹配时在Home页面默认显示的内容。

总结:

  • 注册子路由是需要写上父路由的path值
  • 路由的匹配是按照注册路由的顺序进行的

路由传参

向路由组件传递params参数

使用方法

  • 向路由组件传递params参数 (在路径后面直接接参数)
 `/home/message/detail/001/消息1`}>{message.title}
  • 注册路由时,接收路由组件传递的params参数 (在路径后面使用 :参数名 进行接收)
Detail}/>
  • 在路由组件中接收传递过来的的参数并使用
    路由传递的参数存储在this.props.match.params 中:
render() {const {id, title} = this.props.match.params
}

例子

Message/index.jsx

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'001', title:'消息1'},{id:'002', title:'消息2'},{id:'003', title:'消息3'}]   }render() {const {messageArr} = this.statereturn (
    {messageArr.map((message) => {return (
  • message.id}>{/* 向路由组件传递params参数 */}`/home/message/detail/${message.id}/${message.title}`}>{message.title}  
  • )})}

{/* 注册路由 */}{/* 接收路由组件传递的params参数 */}Detail}/>
)} }

Detail/index.jsx

import React, { Component } from 'react'export default class Detail extends Component {state = {dataDetail:[{id: '001', context: '我是消息1的内容'},{id: '002', context: '我是消息2的内容'},{id: '003', context: '我是消息3的内容'},]}render() {const {id, title} = this.props.match.paramsconst {dataDetail} = this.state const findDetail = dataDetail.find((detailObj) => {return detailObj.id === id})return (
ID: {id}
TITLE: {title}
Context:{findDetail.context}
)} }

在这里插入图片描述

向路由组件传递search参数(query参数)

补充:qs库

  • qs库 可以使用stringify()方法将 对象格式转换为urlencoded编码格式 (key=value&key=value)
    eg:
import qs from 'qs'let obj = {name:'yang', age:20}
// 转成 urlencoded格式 (key=value&key=value)
console.log(qs.stringify(obj));

输出:

name=yang&age=20
  • qs库 可以使用parse()方法将urlencoded编码格式 转换为对象格式
console.log(qs.parse('name=yang&age=20'))

输出:

{name: 'yang', age: '20'}

使用方式

  • 向路由组件传递search参数 (在路径后面直接接参数)
 `/home/message/detail?id=${message.id}&title=${message.title}`}>{message.title}
  • 注册路由时,无需接收search参数
Detail}/>
  • 在路由组件中接收传递过来的的参数并使用
    路由传递的参数存储在this.props.location.search 中:
    但是还参数是未解析的状态,即urlencoded编码格式,需要借助qs库进行解析
  render() {// 接收search参数const {search}  = this.props.location// slice(1)是为了去掉参数传递时的问号const {id, title} = qs.parse(search.slice(1))}

例子

Message/index.jsx

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'001', title:'消息1'},{id:'002', title:'消息2'},{id:'003', title:'消息3'}]   }render() {const {messageArr} = this.statereturn (
    {messageArr.map((message) => {return (
  • message.id}>{/* 向路由组件传递params参数 */}{/* {message.title}   */}{/* 向路由组件传递search参数 */}`/home/message/detail/?id=${message.id}&title=${message.title}`}>{message.title}  
  • )})}

{/* 注册路由 */}{/* 接收路由组件传递的params参数 */}{/* */}{/* search参数无需接受 */}Detail}/>
)} }

Detail/index.jsx

import React, { Component } from 'react'
import qs from 'qs'let obj = {name:'yang', age:20}
// 转成 urlencoded格式 (key=value&key=value)
console.log(qs.stringify(obj));console.log(qs.parse('name=yang&age=20'))export default class Detail extends Component {state = {dataDetail:[{id: '001', context: '我是消息1的内容'},{id: '002', context: '我是消息2的内容'},{id: '003', context: '我是消息3的内容'},]}render() {// 接收params参数// const {id, title} = this.props.match.params// 接收search参数const {search}  = this.props.locationconst {id, title} = qs.parse(search.slice(1))const {dataDetail} = this.state const findDetail = dataDetail.find((detailObj) => {return detailObj.id === id})return (
ID: {id}
TITLE: {title}
Context:{findDetail.context}
)} }

向路由组件传递state参数

params参数和search参数都会显示在地址栏中,但是state参数就不会显示在地址栏上

使用方式

  • 向路由组件传递state参数 (在路径后面直接接参数)
{pathname:'/home/message/detail', state:{id:message.id, title:message.title }}}>{message.title}
  • 注册路由时,无需接收state参数
Detail}/>
  • 在路由组件中接收传递过来的的参数并使用
    路由传递的参数存储在this.props.location.state 中,是对象格式
  render() {const {id, title} = this.props.location.state }

例子

Message/index.jsx

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'001', title:'消息1'},{id:'002', title:'消息2'},{id:'003', title:'消息3'}]   }render() {const {messageArr} = this.statereturn (
    {messageArr.map((message) => {return (
  • message.id}>{/* 向路由组件传递params参数 */}{/* {message.title}   */}{/* 向路由组件传递search参数 */}{/* {message.title}   */}{/* 向路由传递state参数 */}{pathname:'/home/message/detail', state:{id:message.id, title:message.title }}}>{message.title}  
  • )})}

{/* 注册路由 */}{/* 接收路由组件传递的params参数 */}{/* */}{/* search参数无需接受 */}{/* */}{/* state参数无需接受 */}Detail}/>
)} }

Message/Detail/index.jsx

import React, { Component } from 'react'
import qs from 'qs'let obj = {name:'yang', age:20}
// 转成 urlencoded格式 (key=value&key=value)
console.log(qs.stringify(obj));console.log(qs.parse('name=yang&age=20'))export default class Detail extends Component {state = {dataDetail:[{id: '001', context: '我是消息1的内容'},{id: '002', context: '我是消息2的内容'},{id: '003', context: '我是消息3的内容'},]}render() {// 接收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 {dataDetail} = this.state const findDetail = dataDetail.find((detailObj) => {return detailObj.id === id}) || {}return (
ID: {id}
TITLE: {title}
Context:{findDetail.context}
)} }

在这里插入图片描述
浏览器地址中没有相关参数信息,但是页面刷新的时候参数不会丢失因为state参数存储在history的location的state中。
state参数是存储在路由组件的history的location的state中的,所以当浏览器的缓存被清空,history就被清空,参数就会丢失,再次访问该地址就无法获取参数就会报错。

路由的两种模式push与replace

浏览器的history会存储我们访问的路径,存储结构是栈结构,存储模式有两种模式push模式和replace模式:

  • push模式:将新访问的路径直接压入栈
  • replace模式:用新访问的路径替换栈顶元素

默认是push模式,可以通过给Link标签添加replace属性即可:

true} to={{pathname:'/home/message/detail', state:{id:message.id, title:message.title }}}>{message.title}

编程式路由导航

可以不通过Link标签来实现路由导航的路由是编程时路由导航,实际上是操作history身上的API。
注意:只有路由组件才有.props.history属性,才能直接使用如下变成式路由导航
this.props.history的API:

  • replace(跳转路径): replace路由跳转
  • push(跳转路径):push路由跳转
  • go(n):前进或后退|n|步
  • goBack():后退1步
  • goForward():前进1步

replace和push方法可以携带不同的参数(param、query、state)进行路由跳转。
replace跳转

   // replace + params参数this.props.history.replace(`/home/message/detail/${id}/${title}`)// replace + query参数this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)// replace + state参数this.props.history.replace(`/home/message/detail`, {id, title})

push跳转

	 // push + params参数this.props.history.push(`/home/message/detail/${id}/${title}`)// push + query参数this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)// push + state参数this.props.history.push(`/home/message/detail`, {id, title})

eg:

message/index.jsx

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'001', title:'消息1'},{id:'002', title:'消息2'},{id:'003', title:'消息3'}]   }replaceShow = (id, title)=>{// replace + params参数// this.props.history.replace(`/home/message/detail/${id}/${title}`)// replace + query参数// this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)// replace + state参数this.props.history.replace(`/home/message/detail`, {id, title})}pushShow = (id, title)=>{// push + params参数// this.props.history.push(`/home/message/detail/${id}/${title}`)// push + query参数// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)// push + state参数this.props.history.push(`/home/message/detail`, {id, title})}back = ()=>{this.props.history.goBack()}forward = ()=>{this.props.history.goForward()}go = ()=>{this.props.history.go(2)}render() {const {messageArr} = this.statereturn (
    {messageArr.map((message) => {return (
  • message.id}>{/* 向路由组件传递params参数 */}{/* {message.title}   */}{/* 向路由组件传递search(query)参数 */}{/* {message.title}   */}{/* 向路由传递state参数 */}{pathname:'/home/message/detail', state:{id:message.id, title:message.title }}}>{message.title}    
  • )})}

{/* 注册路由 */}{/* 接收路由组件传递的params参数 */}{/* */}{/* search参数无需接受 */}{/* */}{/* state参数无需接受 */}Detail}/>
)} }

message/detail/index.jsx
不同的参数接收方式也要做出相应的改变

import React, { Component } from 'react'
import qs from 'qs'let obj = {name:'yang', age:20}
// 转成 urlencoded格式 (key=value&key=value)
console.log(qs.stringify(obj));console.log(qs.parse('name=yang&age=20'))export default class Detail extends Component {state = {dataDetail:[{id: '001', context: '我是消息1的内容'},{id: '002', context: '我是消息2的内容'},{id: '003', context: '我是消息3的内容'},]}render() {// 接收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 {dataDetail} = this.state const findDetail = dataDetail.find((detailObj) => {return detailObj.id === id}) || {}return (
ID: {id}
TITLE: {title}
Context:{findDetail.context}
)} }

在这里插入图片描述

withRouter的使用(一般组件实现编程式路由导航)

注意:由于一般组件身上没有.props.history属性,但是如果还是想要实现编程式路由导航可以借助withRouter实现
withRouter可以加工一般组件,让一般组件具备路由组件特有的API(props.history等)
withRouter的返回值是一个带有路由组件API的新组件。
使用:
Header/index.jsx(Header组件是一个一般组件)

import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'class Header extends Component {back = ()=>{this.props.history.goBack()}forward = ()=>{this.props.history.goForward()}go = ()=>{this.props.history.go(2)}render() {return (

React Router Demo

)} }export default withRouter(Header) // withRouter可以加工一般组件,让一般组件具备路由组件特有的API(props.history等)

BrowserRouter 和 HashRouter的区别

  1. 底层原理不一样:
    BrowserRouter使用的是H5的history API(注意不是组件实例身上的history),不兼容IE9及以下版本。
    HashRouter使用的是URL的哈希值
  2. url表现形式不一样
    BrowserRouter的路径中没有#,例如: localhost:3000/demo/test
    HashRouter的路径包含#,例如: localhost:3000/#/demo/test
  3. 刷新后对路由state参数的影响
    因为state保存在history对象中,页面刷新并不会关闭浏览器,有记忆功能,所以BrowserRouter没有任何影响
    但是HashRouter刷新后会导致路由state参数的丢失。
  4. 备注: HashRouter可以用于解决一些路径错误相关的问题。HashRouter不会将URL的哈希值(即#后面的值)传给服务器。

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...