React 路由

304 阅读4分钟

什么是 react-router 及实现方式

ract-router

  • 不同的路径渲染不同的组件

指定一个 Route 组件要渲染的内容,有三种方式:

  • component 属性,值是一个组件的类型,他不能写定义的逻辑
<Route path='/home' component={Home}></Route>
  • render 属性,它是一个函数,如果路径匹配的话,就要渲染它这个函数的返回值
<Route path='/' render={() => <h2>world</h2>}></Route>
  • children 属性,它也是一个函数

实现方式,有两种:

  • HashRouter:利用 hash 实现路由切换
  • BrowserRouter:实现 H5 Api 路由的切换
  • 两种实现方式其内部都是调用了 react-router 库中的router,只不过分别传入了不同的 history 对象

HashRouter

  • 利用 hash 实现路由切换
  • hashchange:每当 hash 值发生变化的话,就会执行回调函数
  • window.location.hash:获取 hash
  • 当前 router 提供的内置组件
    • HashRouter
    • Router:渲染容器,只有一个
    • Route:路由规则
  • 使用 HashRouter 把根组件包裹起来「只包裹在最外层即可」,谁用到了组件,包裹谁的根组件
  • 参数
    • path:指定路径,一个路径对应一个组件
    • component:要展示的组件,只是展示页面渲染
    • render:函数体返回的组件 <Route path='/' render={() =>

      world

      }>
    • 如果存在逻辑判断,使用 render
    • 只要路径上包含:/,都会渲染到页面上
    • route 会从上到下依次匹配,匹配到则渲染,路径匹配不上的都显示为空标签
    • 页面的路径跟谁能匹配上,该行代码就会被替换成相应的组件
    • exact:精确匹配,只有完全跟路径匹配的情况下才会渲染
<HashRouter>
    <Route path='/home' exact component={Home}></Route>
<HashRouter/>
  • 链接上会多一个:# 号,# 号后面都称为 hash
  • hash 的特点:hash 改变页面不会刷新
  • 渲染组件时交给了 Route 来处理,它会默认给我们传递一些参数:根据路径的匹配传递参数
    • history:放的一些方法「push、replace」
    • location:原生方法一样
    • match:匹配到路径的信息
      • isExact
      • params
      • path
      • url
<HashRouter>
   <Route exact={true} path="/" component={Home} />
   <Route path="/User" component={Home} />
</HashRouter>

BrowserRouter

  • 利用 H5 API 实现路由的切换
  • html5 History API 包括两个方法:history.pushState() 和 history.replaceState(),和一个事件 window.onpopstate
    • history.pushState(stateObject, title, url)
      • 第一个参数:存储 URL 对应的状态对象,该对象可在onpopstate 事件中获取,也可以在 history 对象中获取
      • 第二个参数:标题,目前浏览器并未实现
      • 第三个参数:设定的 URL
      • pushState 函数向浏览器的历史堆栈中压入一个 URL 为设定值的记录,并改变历史堆栈的当前指针至栈顶
    • history.replaceState()
      • 参数与 pushState 相同,含义也相同
      • 唯一的区别在于 replaceState 是替换浏览器历史堆栈的,当前历史记录为设定的 URL
      • replaceState 不会改动浏览器历史隧站的当前指针
    • window.onpopstate
      • window 的属性
      • 该事件会在调用浏览器的前进、后退以及执行 history.forward、history.back 和 history.go 触发,这些操作都会修改历史堆栈的当前指针,History 栈是不会变的
      • 在不改变 document 的前提下,一旦当前指针改变则会触发 onpopstate 事件

Switch 组件:优化性能

  • switch 包起来的 Route 只要有一个匹配上了,下边就不在匹配
  • 使用 switch 不能用元素包裹起来
<Switch>
  <Redirect path='/' exact to='/home'></Redirect>
  <Route path='/qq' render={(props) => GetQuery(QQ, props)}></Route>
  <Route path='/login' component={Login}></Route>
  <Route path='/*' render={() => <NoFound />}></Route>
</Switch>    
    

Redirect:路由重定向

  • 如果所有路由都没有匹配到的话,会执行 Redireact
  • Redireact 必须配合 Switch 使用
  • 参数
    • path:匹配到重定向的路径
    • to:重定向到哪个组件
<Switch>
  <Redirect path='/' exact to='/home'></Redirect>
  <Route path='/login' component={Login}></Route>
  <Redirect path='/' exact to='/home'></Redirect>
</Switch>    

Link

  • 用来生成点击跳转:a 标签
  • 用 Link 组件必须结合 to 属性来使用,会渲染成可以点击跳转的标签
  • 参数:to 就是跳到哪里
  • 使用方法
<Link to="/home"><Link/>

路由嵌套

  • 哪个组件下的路由嵌套,就在哪个组件文件下进行路由嵌套即可
  • 示例 在 home 组件中嵌套路由
<Route path='/home/a' component={MyA}></Route>
<Route path='/home/b' component={MyB}></Route> 

受保护的路由

  • 比如:登录之后可以跳转显示的页面
  • 登录之后可以访问 user,否则跳转到 login
  • 使用方法
<Protect path='/user' component={User} level={4}></Protect>	

NavLink 组件

  • 可点击跳转的标签,自动添加 class 类名:active

路径404

  • 路径都匹配不上的话,展示 404
<Route path='/*' render={() => <NoFound />}></Route>

withRouter

实现原理

  • 创建一个 routerContext 文件
import React from 'react'
const RouterContext = React.createContext();// 创建一个全局上下文
export default RouterContext;
  • 根组件进行赋值
<RouterContext.Provider value={// 传给子组件的值}>
	{this.props.children}// 儿子们
</RouterContext.Provider>
  • 创建一个处理组件的 js 文件,最终返回一个被 RouterContext.Consumer 包裹的新组件
import RouterContext from '../routerContext'
function withRouter(OldComponent) {
  return props=>{
    <RouterContext.Consumer>
      {
        value=>{
            return <OldComponent {...props} {...value}>
        }
      }
    </RouterContext.Consumer>
  }
}
  • 经过处理后,儿子们都可以拿到 props 中的属性,比如:history、location...

Prompt:弹出框

  • 使用场景:编辑文字,如果输入框中有值,值不为空,就需要阻止,否则不阻止
  • 属性:
    • when 属性:true 阻止,false 不阻止
    • message:提示内容

路由 hooks

  • 直接调用相应的 hook,便可获取 props 中相应的属性及值
    • useHistory
    • useLocation
    • useParams

组件懒加载

插件:react-loadable