React Router的使用

React Router

现代的前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生。

  • 前端路由功能:让用户从一个视图(组件)导航到另一个视图(组件)
  • 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系
  • 使用React路由简单来说,就是配置路径和组件
  • React Router的使用

React Router 的使用

  • 安装 npm i -S react-router-dom / yarn add react-router-dom

相关组件**

  • Router组件:包裹整个应用,一个React应用只需要使用一次
    Router: HashRouter和BrowserRouter
    • BrowserRouter:使用H5的history API实现(localhost3000/first)
    • HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)
  • Link/NavLink组件:用于指定导航链接(a标签)
    最终Link会编译成a标签,而to属性会被编译成 a标签的href属性
  • Route组件:指定路由展示组件相关信息(组件渲染)
    path属性:路由规则,这里需要跟Link组件里面to属性的值一致
    component属性:展示的组件
  • Redirect组件: 重定向
		<Switch>
    # 重定向 from从哪里来 to重定向到何处去
    <Redirect from="/" to="/film" />
    # 404设置
    <Route component={Notfound} />
</Switch>
  • Switch组件:
    因为react-router是懒匹配,当有多个路由时会从上到下进行模糊匹配,只要符合要求就会进入路由,于是常常会出现进入我们不想进入的组件中,switch可以精确匹配 并且只匹配一个路由就会停止
  • withRouter高阶组件: (为了传递this.props.history)
    把不是通过路由直接渲染出来的组件,将react-router 的 history、location、match 三个对象传入props对象上
    默认情况下必须是经过路由匹配渲染的组件才存在this.props,才拥有路由参数,才能使用编程式导航的写法,执行this.props.history.push(’/uri’)跳转到对应路由的页面,然而不是所有组件都直接与路由相连的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,此时就可以使用this.props
// 引入withRouter
import { withRouter} from 'react-router-dom'

// 执行一下withRouter
export default withRouter(Cmp)

导航方式

  • 声明式导航

    使用Link或NavLink组件完成声明式导航的定义
    Link/NavLink区别

    • Link组件不会根据路由的变化而添加或修改编译后html标签中的属性
    • NavLink会根据路由的变化而自动修改编译后html标签中的属性
      如果当前的路由规则和Navlink中的To所写的规则一致则添加class样式,
      默认名称为active,可以通过activeClassName来修改匹配成功后样式名称。
  • 编程式导航
    react-router-dom中通过history对象中的push/replace/go等方法实现编程式导航功能。

this.props.history.push({
  pathname: "/home",
  search: "from=404",	// 表示传递查询字符串
  state: {		// 隐式传参,地址栏不体现
    username: "admin",
  },
});

注! 重要:在react路由中this.props要想得到路由中的对象,则默认必须要通过路由规则匹配渲染的组件才能有此对象 - 必须是直接渲染的组件,因为涉及到路由参数的传递和编程式导航

传参方式

  • 动态路由参数(param)
    以“/detail/:id”形式传递的数据 在落地组件中通过this.props.match.params得到
    常用于详情页跳转
  • 查询字符串(query)
    通过地址栏中的 ?key=value&key=value传递 在落地组件中通过this.props.location.search得到
    用于搜索跳转
  • 隐式传参(state),通过地址栏是观察不到的
    通过路由对象中的state属性进行数据传递 在落地组件中通过this.props.location.state得到
    埋点 以及账号密码跳转

三种路由渲染方式(面试常问) 共5种

//component (组件对象或函数)

<Route path="/home" component={Home} /><Route path="/home" component={(router)=><Home {…router} />} />

//render (函数)
<Route path="/home" render={router=><Home {…router} />} />
	children (函数或组件)

// 全匹配
<Route path="/about" children={router =>{
	return <div>children渲染</div>
}} />// 精确匹配
<Route path="/about" children={<About />} />

5种路由渲染方式的区别

  • 组件渲染和回调函数的渲染的区别
    • 回调函数的形式可以在函数内写逻辑进行判断而直接渲染组件不行
    • 同时回调函数的组件收不到 路由对象 需要手动传递
  • 关于component和render的回调函数的区别
    • component的回调的每次跳转都会销毁原先的页面重新加载 而render不会 从性能优化上来说 我们最好选择render回调 除非特殊情况 需要每次跳转都要执行函数
  • 关于children精确匹配基本没用 而全匹配可以帮助我们处理不管是否跳转页面都显示该路由
    • children属性和component/render一样,也会接受所有由route传入的所有参数。不过当一个路由匹配失败时,match为null。那么无论路由是否匹配,都可以让我们动态更改要渲染的组件了。
    • 全匹配可以处理那种首页导航 无论是否跳转页面都会显示 但是如果不是匹配路由就会接收不到this.props的参数 这样就可以判断是否是当前路由

自定义导航组件

为何需要自定义导航?

因为在项目中往往不是所有的声明式导航都是需要a标签完成,有时候可能需要别的标签,此时如果在需要的地方去写编程式导航就会有代码重复可能性,就在对于公共代码进行提取。

  • 定义一个普通组件可以是类组件也可以是函数式组件
  • 父组件能向子组件传值 props
  • 此高阶组件不管路由规则是否匹配都要有渲染 children
import React, { Component } from 'react';
import { Route,withRouter } from 'react-router-dom'

import Storage from '@/utils/storage'

@withRouter
class AuthRouter extends Component {

  // 判断用户是否登录过
  checkLogin() {
    if (Storage.get('islogin')) {
      return true
    }
    return false;
  }

  render() {
    const Cmp = this.props.cmp

    return (
      <>
        {this.checkLogin() ?
          <Route path={this.props.path} render={router => {
            return <Cmp {...router} />
          }} />
          :
          this.props.history.push('/login')
        }
      </>
    );
  }
}

export default AuthRouter;

等于二层嵌套 在第一层中是可以收到this.props 但是第二层不可以 所以需要配合withRouter一起使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MaxLoongLvs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值