React学习计划-React16--React基础(六)路由

路由

一、版本5路由

1. react-router-dom
2. 路由的使用
1. 基础使用
  1. 安装:yarn add react-router-dom@5
  2. 明确好界面中的导航区、展示区
  3. 导航区Link标签包裹
    <Link to="/home">Home</Link>
  4. 展示区写在Route标签进行匹配
    <Route path='/home' component={Home} />
  5. <App/>最外侧包裹一个<BrowserRouter>或者<HashRouter>
2. 路由组件和一般组件
  1. 写法不同:
    • 一般组件: <Demo/>
    • 路由组件: <Route path='/home' component={Home} />
  2. 存放位置不同:
    • 一般组件写在components文件夹
    • 路由组件一般写在pages文件夹中,
  3. 接收到的props不同:
    • 一般组件:写组件标签时传递了什么,就能收到什么

    • 路由组件:接收三个固定的属性(常用)

      history:
      go: ƒ go(n)
      goBack: ƒ goBack()
      goForward: ƒ goForward()
      push: ƒ push(path, state)
      replace: ƒ replace(path, state)
      location:
      pathname: "/home"
      search: ""
      state: undefined
      match:
      params: {}
      path: "/home"
      url: "/home"

  1. NavLink 可以实现路由链接的高亮,通过activeClassName指定样式名
  2. 标签体内容是一个特殊的标签属性
  3. 通过this.props.children可以获取标签体内容

使用NavLink

封装NavLink

4.Switch的使用
  1. 通常情况下,pathcomponent是一一对应的关系
  2. Switch可以提高路由匹配效率(单一匹配)
5. 解决多级路径刷新页面样式丢失的问题
  1. publick/index.html中,引入样式时不写.//(常用)
  2. publick/index.html中,引入样式时不写./%PUBLIC_URL%(常用)
  3. 使用HashRouter
  4. 原因:加载不存在的路径时,默认把publick/index.html返回
6. 路由的模糊匹配和严格匹配exact
  1. 默认使用的使模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序一致)
  2. 开启严格匹配,<Route exact path='/about' component={About}/>
  3. 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
7. Redirect的使用
  1. 一般写在所以路由注册的最下方,当所以路由无法匹配时,跳转到Redirect指定的路由

  2. 编码

    <Switch> <Route path='/home' component={Home} /> <Route path='/about' component={About} /> {/* 写在最底部,重定向, 路由都匹配不上,就去 to ... */} <Redirect to='/home'/> </Switch>
8. 嵌套路由
  1. 注册子路由时要写上父路由的path
  2. 路由的匹配是按照注册路由的顺序进行的
9. 向路由组件传递参数
1. params参数
  1. 路由链接(携带参数):

    <Link to={`/about/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
  2. 注册路由(声明接收):

    <Route path='/about/message/detail/:id/:title' component={Detail}/>
  3. 接收参数:const {id, title} = this.props.match.params

2. search参数
  1. 路由链接(携带参数):

    <Link to={`/about/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link>
  2. search参数无需声明接收,正常注册路由即可:

    <Route path='/about/message/detail' component={Detail}/>
  3. 接收参数:

    // search 接收参数 react自动安装的库
    import qs from 'querystring'
    const {search} = this.props.location
    const {id, title} = qs.parse(search.slice(1))

  4. 备注: 获取到searchurlencoded编码,需要借助querystring解析

3. state传递参数
  1. 路由链接(携带参数):

    <Link to={{pathname:'/about/message/detail', state:{ id: item.id, title: item.title }}}>{item.title}</Link>
  2. 注册路由(声明接收):

    // state参数无需声明接收,正常注册路由即可
    <Route path='/about/message/detail' component={Detail}/>

  3. 接收参数:const {id, title} = this.props.match.state

  4. 备注: 刷新也可以保留住参数

9. pushreplace
  1. 加上replace属性,将不会再进行压栈,浏览器不会有回退记录

    <MyNavLink replace to='/about/message'>Message</MyNavLink>

10. 编程式导航

借助this.props.history对象上的API对操作路由跳转、前进、后退

复制代码
  this.props.history.push()
  this.props.history.replace()
  this.props.history.goBack()
  this.props.history.goForward()
  this.props.history.go()
11. withRouter
  1. withRouter 可以加工一般组件,让一般组件具备路由组件所持有的API

  2. withRouter的返回值是一个新组件

    import { withRouter } from 'react-router-dom'
    export default withRouter(Hearder)

示例中:普通组件想要实现路由跳转

App.js中:

12. BrowserRouterHashRouter的区别
  1. 底层原理不同:
    BrowserRouter使用的使H5historyAPI,不兼容IE9及以下版本,
    HashRouter使用的使URL的哈希值
  2. path表现形式不一样
    BrowserRouter的路径中间没有#,例如:localhost:3000/demo/test
    HashRouter的路径包含#,例如:localhost:3000/#/demo/test
  3. 刷新后对路由state参数的影响
    BrowserRouter没有影响,因为state保存在history对象中
    HashRouter刷新后会导致路由state参数丢失
  4. 备注:HashRouter可以用于解决一些路径错误相关的问题

二、版本6路由

1. 概述
  1. react Router 三个不同的包发布在npm上:它们分别是:
    1. react-router: 路由的核心库,提供很多的:组件,钩子
    2. react-router-dom: 包含react-router所以内容,并添加一些专门用于DOM组件。例如<BrowerRouter>
    3. react-router-native: 包含react-router所以内容,并添加一些专门用于ReactNativeAPI。例如<NativeRouter>
  2. React Router 5.x版本相比,改变了什么?
    1. 内置组件的变化:移除<Switch/>,新增<Routes/>
    2. 语法的变化:component={About}变为elemet={<About/>}
    3. 新增多个hook:useParamsuseNavigateuseMatch
    4. 官方明确推荐函数式组件了!!!
      ...
2. Component
1. <BerwserRouter>
2. <HashRouter>
3. <Routes/>和<Route/>
  1. v6版本中移除了<Switch>,引入了新的替代者:<Routes>

  2. <Routes><Route>要配合使用,且必须要用<Routes>包裹<Route>

  3. <Route>相当于一个if语句,如果其路径与当前URL匹配,则呈现其对应的组件

  4. <Route caseSensitive>属性用于指定:匹配时是否区分大小写(默认为fasle

  5. URL发生变化时,<Routes>都会查看其所有子<Route>元素以找到最佳匹配并呈现组件

  6. <Route>也可以嵌套使用,且配合useRoutes()配置"路由表",但需要通过<Outlet>组件来渲染其子路由(见<Outlet/>说明)

  7. 示例代码:

    // 路由表
    const element = useRoutes({
    path: '/home',
    element: <Home/>
    },
    {
    path: '/about',
    element: <About/>,
    children: [
    {
    path: 'news',
    element: <News/>,
    },
    {
    path: 'message',
    element: <Message/>,
    children: [
    {
    path: 'detail',
    element: <Detail/>
    }
    ]
    }
    ]
    },
    {
    path: '/',
    element: <Navigate to='/about'/>
    }
    ])
    return (
    <>
    {/* 1. 在react中靠路由实现切换组件--编写路由链接 */}
    <NavLink className={okTive} to='/home'>Home</NavLink>


    <NavLink className={okTive} to='/about'>About</NavLink>

    复制代码
     {/* 2. 注册路由 */}
     <hr/>
     {/* Routes注册*/}
     {/* <Routes> 
       <Route path='/home' element={<Home/>} />
       <Route path='/About' element={<About/>} />
       <Route path='/' element={<Navigate to="/about"/>}/>
     </Routes> */}
     {/* 路由表注册*/}
     {element}
     </>

    )

4. <Link>
  1. 作用:修改URL,且不发送网络请求(路由链接)
  2. 注意: 外侧要用<BrowserRouter/><HashRouter/>包裹
5. <NavLink>
  1. 作用:与<Link>组件类似,且可实现导航的高亮效果
6. <Navigate>
  1. 作用:只要<Navigate>组件被渲染,就会修改路径,切换视图

  2. replace属性用于控制跳转模式,(pushreplace,默认是push)

  3. 实例代码:

    import {useState} from 'react'
    import {Navigate} from 'react-router-dom'

    export default function Home() {
    const [num, setNum] = useState(1)

    return (
    <>
    {num === 2
    ? <Navigate to='/about' replace/>
    :

    num的值是{num}

    }
    <button onClick={() => setNum(2)}>点击</button>
    </>
    )
    }

7. <Outlet>
  1. <Route>产生嵌套是,渲染其对应的后续子路由

  2. 示例代码:

    • {/* <NavLink className={okTive} to='news'>News</NavLink> */} {/* <NavLink className={okTive} to='/about/news'>News</NavLink> */} <NavLink className={okTive} to='./news'>News</NavLink>
    • <NavLink className={okTive} to='message'>Message</NavLink>
    {/* 指定路由组件呈现的位置(二级+路由) */} <Outlet/>
3. HOOKS
1. useRoutes()
  1. 根据路由表,动态创建<Routes><Route>
2. useNavigate()
  1. 作用:返回一个函数用来实现编程式导航

  2. 示例代码:

    import { useNavigate } from 'react-router-dom'

    export default function Hearder() {
    const navigate = useNavigate()

    const back = () => {
    navigate(-1)
    }

    const forward = () => {
    navigate(1)
    }

    const handleClick = () => {
    navigate('detail',{
    replace: false,
    state: {
    id: '122',
    title: '小明',
    content: '热爱祖国'
    }
    })
    }
    return (
    <>
    <button onClick={back}>后退</button>
    <button onClick={forward}>前进</button>
    <button onClick={handleClick}>跳转详情</button>
    </>
    )
    }

3. useParams()
  1. 作用: 当前匹配路由的params参数
4. useSearchParams()
  1. 作用: 用于读取和修改当前位置的URL中的查询字符串
  2. 返回一个包含两个值的数组,内容分别为:当前的search参数、更新search的函数
5. useLocation()
  1. 作用:获取当前location信息,对标5.x中的路由组件的localtion属性(可用于获取state参数)
6. useMatch()
  1. 作用:返回当前匹配信息,对标5.x中的路由组件的match属性
7. useInRouterContext()(APP.jsx)
  1. 作用:如果组件在<Router/>的上下文中呈现(被路由包裹的组件),则useRouterContext钩子返回true,否则false
8. useNavigationType()(News.jsx)
  1. 作用:返回当前的导航类型(用户是如何来到当前页面的)
  2. 返回值:POP,PUSH,REPLACE
  3. 备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)
9. useOutlet()(About.jsx)
  1. 作用:用来呈现当前组件中要渲染的嵌套路由

  2. 示例代码:

    const a = useOutlet()
    console.log(a, 'useOutlet嵌套')
    // 如果嵌套路由没有挂载,则a为null
    // 如果嵌套路由已经挂载,则展示嵌套路由对象

10. useResolvedPath()(News.jsx)
  1. 作用:给定一个URL值,解析其中的:pathsearchhash
相关推荐
JosieBook几秒前
【Web应用】若依框架:基础篇14 源码阅读-后端代码分析-课程管理模块前后端代码分析
前端
前端小嘎5 分钟前
被大厂裁员后做的前端工具网站
前端
超级土豆粉5 分钟前
CSS 预处理器与工具
前端·css
月初,12 分钟前
MongoDB学习和应用(高效的非关系型数据库)
学习·mongodb·nosql
哼唧唧_23 分钟前
使用 React Native 开发鸿蒙(HarmonyOS)运动健康类应用的系统化准备工作
react native·react.js·harmonyos·harmony os5·运动健康
Jackson__30 分钟前
聊聊 JS 中的可选链 ?.
前端
前端小崔36 分钟前
前端面试题之ES6保姆级教程
开发语言·前端·javascript·面试·职场和发展·ecmascript·es6
casual_clover41 分钟前
Android 之 kotlin 语言学习笔记四(Android KTX)
android·学习·kotlin
Bug从此不上门1 小时前
【无标题】
前端·javascript·uni-app·vue
HarderCoder1 小时前
ByAI:Redux中间件的原理和ts简化实现
前端·redux