黑马React18: ReactRouter

黑马React: ReactRouter

Date: November 21, 2023

Sum: React路由基础、路由导航、导航传参、嵌套路由配置

路由快速上手



1. 什么是前端路由

一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候,path 对应的组件会在页面中进行渲染



2. 创建路由开发环境

bash 复制代码
# 使用CRA创建项目
npx create-react-app react-router-pro

# 安装最新的ReactRouter包
npm i react-router-dom

# 启动项目
npm run start


3. 快速开始

jsx 复制代码
import React from 'react'
import ReactDOM from 'react-dom/client'

const router = createBrowserRouter([
  {
    path:'/login',
    element: <div>登录</div>
  },
  {
    path:'/article',
    element: <div>文章</div>
  }
])

ReactDOM.createRoot(document.getElementById('root')).render(
  <RouterProvider router={router}/>
)



抽象路由模块




路由导航

1. 什么是路由导航

路由系统中的多个路由之间需要进行路由跳转,并且在跳转的同时有可能需要传递参数进行通信



2. 声明式导航

声明式导航是指通过在模版中通过 组件描述出要跳转到哪里去,比如后台管理系统的左侧菜单通常使用这种方式进行

jsx 复制代码
<Link to="/article">文章</Link>

语法说明:通过给组件的to属性指定要跳转到路由path,组件会被渲染为浏览器支持的a链接,如果需要传参直接通过字符串拼接的方式拼接参数即可



3. 编程式导航

编程式导航是指通过 useNavigate 钩子得到导航方法,然后通过调用方法以命令式的形式进行路由跳转,比如想在登录请求完毕之后跳转就可以选择这种方式,更加灵活

语法说明:通过调用navigate方法传入地址path实现跳转

jsx 复制代码
import { Link, useNavigate } from 'react-router-dom'

const Login = () => {
  const navigate = useNavigate()
  return (
    <div>
      我是登陆页
      {/* 声明式写法 */}
      <Link to="/article">跳转到文章页</Link>
      {/* 命令式写法 */}
      <button onClick={() => navigate('/article')}>跳转到文章页</button>
    </div>
  )
}

export default Login



导航传参

searchParams传参:

src/page/Article/index.js

jsx 复制代码
import { useSearchParams } from "react-router-dom"

const Artitlce = () => {
  const [params] = useSearchParams()
  const id = params.get('id')
  const name = params.get('name')
  return <div>我是文章页 - {id} - {name}</div>
}

export default Artitlce

params传参:

src/page/Article/index.js

jsx 复制代码
import { useSearchParams, useParams } from "react-router-dom"

const Artitlce = () => {
  // const [params] = useSearchParams()
  // const id = params.get('id')
  // const name = params.get('name')

  const params = useParams()
  let id = params.id
  let name = params.name
  // return <div>我是文章页 - {id} - {name}</div>
  return <div>我是文章页 - {id} - {name}</div>
}

export default Artitlce

src/router/index.js

jsx 复制代码
import Login from '../page/Login/index'
import Article from '../page/Article/index'

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

const router = createBrowserRouter([
  {
    path: '/login',
    element: <Login/>
  },
  {
    // path: '/article',
    path: '/article/:id/:name', // 配置router中的id与name
    element: <Article/>
  },
])

export default router

注意:采用 params 这种方式需要配置一波router




嵌套路由配置

1. 什么是嵌套路由

在一级路由中又内嵌了其他路由,这种关系就叫做嵌套路由,嵌套至一级路由内的路由又称作二级路由,例如:



2. 嵌套路由配置

实现步骤:

  1. 使用 children属性配置路由嵌套关系

  2. 使用 <Outlet/> 组件配置二级路由渲染位置

Case:

Code:

router/index.js

jsx 复制代码
const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout/>,
    children: [
      {
        path: 'board',
        element: <Board/>
      },
      {
        path: 'About',
        element: <About/>
      }
    ]
  },
  {
    path: '/login',
    element: <Login/>,
  },
  {
    // path: '/article',
    path: '/article/:id/:name',
    element: <Article/>
  },
])

src/page/Layout/index.js

jsx 复制代码
const Layout = () => {
  return (
    <div>
      我是一级路由layout组件
      --
      <Link to="/board">面板</Link>
      --
      <Link to="/about">关于</Link>
      {/* 配置二级路由出口 */}
      <Outlet></Outlet>
    </div>
  )
}

Res:

拓展

路由出口:路径匹配的组件显示的位置

参考:路由出口的基础知识

Vue2:路由



3. 默认二级路由

需求:默认就显示二级路由,比如默认显示面板

当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index属性为true

router.js

jsx 复制代码
const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout/>,
    children: [
      {
        index: true,  // 默认显示 index
        element: <Board/>
      },
      {
        path: 'About',
        element: <About/>
      }
    ]
  },
  {
    path: '/login',
    element: <Login/>,
  },
  {
    // path: '/article',
    path: '/article/:id/:name',
    element: <Article/>
  },
])

Layout/index.js

这里需要把

jsx 复制代码
import { Outlet, Link } from "react-router-dom"
import Board from "../Board"
import About from "../About"

const Layout = () => {
  return (
    <div>
      我是一级路由layout组件
      --
      <Link to="/">面板</Link> // 修改原来的 to="/board" 变为 to="/"
      --
      <Link to="/about">关于</Link>
      {/* 配置二级路由出口 */}
      <Outlet></Outlet>
    </div>
  )
}

export default Layout


4. 404路由配置

场景:当浏览器输入url的路径在整个路由配置中都找不到对应的 path,为了用户体验,可以使用 404 兜底组件进行渲染

实现步骤

  1. 准备一个NotFound组件
  2. 在路由表数组的末尾,以*号作为路由path配置路由
    ![

page/NotFound

jsx 复制代码
const NotFound = () => {
  return (
    <div>
      this is not found
    </div>
  )
}

export default NotFound

router/index.js

jsx 复制代码
import Login from '../page/Login/index'
import Article from '../page/Article/index'
import Layout from '../page/Layout'
import About from '../page/About'
import Board from '../page/Board'
import NotFound from '../page/NotFound'

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

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout/>,
    children: [
      {
        index: true,
        element: <Board/>
      },
      {
        path: 'About',
        element: <About/>
      }
    ]
  },
  {
    path: '/login',
    element: <Login/>,
  },
  {
    // path: '/article',
    path: '/article/:id/:name',
    element: <Article/>
  },
  {
    path: '*',
    element: <NotFound/>
  }
])

export default router


5. 俩种路由模式

各个主流框架的路由常用的路由模式有俩种,history模式和hash模式, ReactRouter分别由 createBrowerRouter 和 createHashRouter 函数负责创建

路由模式 url表现 底层原理 是否需要后端支持
history url/login history对象 + pushState事件 需要
hash url/#/login 监听hashChange事件 不需要

Code:

history模式

jsx 复制代码
import { createBrowserRouter } from 'react-router-dom'

const router = createBrowserRouter([

Res:

hash模式

jsx 复制代码
import { createBrowserRouter, createHashRouter } from 'react-router-dom'

const router = createHashRouter([

Res:



相关推荐
光影少年5 天前
react18更新哪些东西
前端·学习·reactjs
cxr8285 天前
Vercel AI SDK 3.0 学习入门指南
前端·人工智能·学习·react.js·typescript·npm·reactjs
光影少年10 天前
react17更新哪些新特性
前端·reactjs
解道Jdon10 天前
AI IDE冲击下JetBrains作死,IDEA埋订阅陷阱
javascript·reactjs
止观止14 天前
React虚拟DOM的进化之路
前端·react.js·前端框架·reactjs·react
解道Jdon1 个月前
最新苹果液体玻璃Liquid Glass效果CSS实现
javascript·reactjs
菜鸡爱上编程1 个月前
React16,17,18,19更新对比
前端·javascript·reactjs·react
stormsha2 个月前
React与原生事件:核心差异与性能对比解析
前端·javascript·react.js·云原生·reactjs
码界奇点2 个月前
React 生命周期与 Hook:从原理到实战全解析
前端·react.js·前端框架·生活·reactjs·photoshop