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

发布时间:2023年12月25日

路由

一、版本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"
    
3. NavLink与封装NavLink
  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>
  1. 注册路由(声明接收):
<Route path='/about/message/detail/:id/:title' component={Detail}/>
  1. 接收参数:const {id, title} = this.props.match.params
2. search参数
  1. 路由链接(携带参数):
<Link to={`/about/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link>
  1. search参数无需声明接收,正常注册路由即可:
 <Route path='/about/message/detail' component={Detail}/>
  1. 接收参数:
// search 接收参数 react自动安装的库
import qs from 'querystring'
const {search} = this.props.location
const {id, title} = qs.parse(search.slice(1))
  1. 备注: 获取到searchurlencoded编码,需要借助querystring解析
3. state传递参数
  1. 路由链接(携带参数):
<Link to={{pathname:'/about/message/detail', state:{
  id: item.id,
  title: item.title
}}}>{item.title}</Link>
  1. 注册路由(声明接收):
// state参数无需声明接收,正常注册路由即可
<Route path='/about/message/detail' component={Detail}/>
  1. 接收参数:const {id, title} = this.props.match.state
  2. 备注: 刷新也可以保留住参数
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>
    <br/>
    <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/> 
        : <h4>num的值是{num}</h4>}
      <button onClick={() => setNum(2)}>点击</button>
    </>
  )
}
7. <Outlet>
  1. <Route>产生嵌套是,渲染其对应的后续子路由
  2. 示例代码:
<div>
  <ul>
    <li>
      {/* <NavLink className={okTive} to='news'>News</NavLink> */}
      {/* <NavLink className={okTive} to='/about/news'>News</NavLink> */}
      <NavLink className={okTive} to='./news'>News</NavLink>
    </li>
    <li>
      <NavLink className={okTive} to='message'>Message</NavLink>
    </li>
  </ul>
  {/* 指定路由组件呈现的位置(二级+路由) */}
  <Outlet/>
</div>
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
文章来源:https://blog.csdn.net/qq_35940731/article/details/135191212
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。