React-router

React-router


React Router现在的版本是6,使用方式相对于之前版本的思想有所不同。之前版本的思想是传统的思想:路由应该统一在一处渲染, Router 4之后是这样的思想:一切皆组件

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.使用方式

  • Route组件的exact属性

exact属性标识是否为严格匹配, 为true是表示严格匹配,为false时为正常匹配。

  • Route组件的render属性而不是component属性

怎么在渲染组件的时候,对组件传递属性呢?使用component的方式是不能直接在组件上添加属性的。所以,React Router的Route组件提供了另一种渲染组件的方式 render, 这个常用于页面组件级别的权限管理。

  • 路由的参数传递与获取

  • Switch组件

总是渲染第一个匹配到的组件

  • 处理404与默认页

  • withRoute高阶组件的使用

  • 管理一个项目路由的方法

  • code spliting

  • HashRouter和BrowserRouter的区别,前端路由和后端路由的区别。



2.React Router基本原理

React Router甚至大部分的前端路由都是依赖于history.js的,它是一个独立的第三方js库。可以用来兼容在不同浏览器、不同环境下对历史记录的管理,拥有统一的API。

  • 老浏览器的history: 通过hash来存储在不同状态下的history信息,对应createHashHistory,通过检测location.hash的值的变化,使用location.replace方法来实现url跳转。通过注册监听window对象上的hashChange事件来监听路由的变化,实现历史记录的回退。
  • 高版本浏览器: 利用HTML5里面的history,对应createBrowserHistory, 使用包括pushStatereplaceState方法来进行跳转。通过注册监听window对象上的popstate事件来监听路由的变化,实现历史记录的回退。
  • node环境下: 在内存中进行历史记录的存储,对应createMemoryHistory。直接在内存里pushpop状态。



3.React-router-dom@5


Route

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

export default function App() {
  return (
    <BrowserRouter>
      <Route path='/a'>A组件</Route>
      <Route path='/b'>B组件</Route>
    </BrowserRouter>
  )
}

通过Route组件来进行组件的显示 path为显示相应组件的url路径

Route组件必须在BrowserRouter组件内使用


Switch

Switch组件会在路径匹配到第一个路由后停止 不会一次匹配多个路由

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

export default function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path='/a'>A1组件</Route>
        <Route path='/a'>A2组件</Route>
        <Route path='/b'>B组件</Route>
      </Switch>
    </BrowserRouter>
  )
}



exact属性

// 路由匹配为模糊匹配 只要Url路径中包含路由路径 都会进行匹配显示
// 为Route组件添加exact属性来精确匹配
<Route path='/a' exact={ true }>A1组件</Route>


Redirect

Redirect组件能实现路由重定向

<Route path='/e'>
	<Redirect to='/a' />
</Route>
// 将Url路径中的路由path换成 Redirect中的to路径



路由显示组件的三种方式

路由的设置方式

        <Route path='/c' render={ ()=>< Cp1 /> } />
        <Route path='/c' component={ Cp1 } />
        <Route path='/c' > < Cp1 />  </Route>

跳转的设置方式

<Link to={{
      pathname:'/d',
      search:'?a=1&b=2',
      hash:'abc',
      state:{ a:1, b:2 }
    }}>跳转方式1</Link>
    
<Link to='/c'>跳转方式2</Link>

<Link to={ () => '/c' }>跳转方式3</Link>

link标签也必须在BrowserRouter组件内

通过to传入对象参数的方式只能在<Route path='/c' component={ Cp1 } />跳转的组件中获取

Navlink是Link的一个特定版本

会在匹配上当前的url的时候给已经渲染的元素添加参数,Link与Navlink的区别:两者都是实现路由的跳转

但点击Link时,url会更新,组件会被重新渲染,但是页面不会重新加载…使用to链接组件时,它的值既可是字符串,也可以是location对象(包含pathname、search、hash、与state属性)如果其值为字符串,将会被转换为location对象

function Cp1(loc) {
  console.log(loc); // loc获取到link的to传入的对象
  return (
    <div>app</div>
  )
}

<Route path='/c' > < Cp1 /> </Route>路径跳转的组件不能接受props传入参数对象
<Route path='/c' render={ ()=>< Cp1 /> } />路径跳转的组件传递参数的方式为

<Route path='/c' render={ ({match, location, history})=>{
      console.log(match, location, history);
      return < Cp1 />
} } />
// render函数形参为一个对象 从中解构出match location history路由对象
// 形参方式无法传入组件内部 可以结合props传入组件
<Route path='/c' render={ (match, location, history)=>{
     console.log(match, location, history);
     return < Cp1 location={location} match={match} history={history} />
} } />



动态路由

<Route path='/e/:abc' component={ Cp2 } />
// 设置 :变量 的方式接收动态参数



路由拦截

<Route path='/center' render={()=>{
	return isAuth()?<Center/>:<Redirect to="/login" />
}} />

通过三目运算符逻辑判断显示组件或是重定向



函数组件中获取路由对象

通过hooks获取路由对象

import { useHistory, useLocation, useParams } from 'react-router-dom'

const Cp3 = ()=> {
  const history = useHistory()
  const location = useLocation()
  const params = useParams()
  return (
    <div>Cp3</div>
  )
}



类组件中获取路由对象

通过withRouter组件

import { Component } from 'react'
import { withRouter } from 'react-router-dom';

class Cp4 extends Component {
  constructor(props){
    super(props)
    console.log(this.props);
  }
  render() {
    return (
      <div>Cp4</div>
    )
  }
}
export default withRouter(Cp4)
// 类组件中通过暴露时调用 withRouter函数 能强制让类组件 通过props来获取路由参数



history对象及路由栈

每次路由跳转时会在路由栈中存入路由数据 使用浏览器前进后退按钮即可在路由栈中相对应进行切换

history对象方法

history.push() 在路由栈后添加一条数据并跳转

history.push('/a')
history.push({
	pathname:'/a',
	search:'?a=1&b=1231',
	state:{}
})

history.replace() 替换路由栈中的最后一条数据并跳转

history.replace({
	pathname:'/a',
	search:'?a=1&b=1231',
	state:{}
})

history.goBack() 加载路由栈中的前一个Url

history.goBack()





路由的应用

在实际开发中需要将路由抽离出来

import { Route } from 'react-router-dom'
import Cp1 from './Cp1'
import Cp2 from './Cp2'
import Cp3 from './Cp3'
import Cp4 from './Cp4'
import Cp5 from './Cp5'

// 将路由放到数组中进行遍历渲染成Route组件

const routes = [
  { name:'home', path:'/home', component: Cp1 },
  { name:'list', path:'/list', component: Cp2 },
  { name:'detil', path:'/detail', component: Cp3 },
  { name:'me', path:'/uc', component: Cp4 },
  { name:'login', path:'/login', component: Cp5 }
]

const Routers = ()=> {
  <>
  	<Route exact={true} path='/'> 	 // 添加首页重定向路由
		<Redirect to='/home' />
	</Route>
    { routes.map(item => <Route path={ item.path } component={ item.component } />) }
    <Route path='*'> 				// 通配符 当匹配不到路径的时候显示404
		404
	</Route>
  </>
}

export default Routers				// 将渲染完成后路由组件暴露 放到根组件的BrowserRouter组件内的Switch组件中





注:

props传入的参数和search传入的参数以及state的参数在页面刷新后仍然存在

当重新打开页面后state会失效 props传入的参数和search传入的参数仍然有效

URLSearchParams

浏览器原生类 用于处理search参数

// 通过URLSearchParams对路由中search传递来的参数进行处理
const query = new URLSearchParams(props.location.search)
// 处理后的对象通过 对象.get()方法获取值
const c = query.get('c')
const d = query.get('d')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raccom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值