• React笔记(六)React路由


    一、React路由简介

    React 官方并没有提供对应的路由插件,因此,我们需要下载第三方的路由插件 —— React Router DOM

    React Router 在 2021 年 11 月份的时候更新 v6 的版本。本次课就主要讲解V6版本

    二、路由配置

    1、下载路由

    在项目根目录中,通过以下命令

    yarn add react-router-dom
    2、路由配置

    1)首先在react项目的入口文件index.js文件中,使用包裹起来

    1. import {BrowserRouter} from 'react-router-dom'
    2. const root = ReactDOM.createRoot(document.getElementById('root'));
    3. root.render(
    4.    <BrowserRouter>
    5.        <App />
    6.    BrowserRouter>
    7. );

    BrowserRouter:包裹这个应用,一个React应用只需使用一次

    在 React Router 中提供了两种路由模式:hash 和 history。

    对应的的路由组件分别是:

    • HashRouter:hash 模式的路由

    • BrowserRouter:history 模式的路由

    实际使用时,任选其中一个模式引入即可

    2)其次,在App.js文件中,使用设置路由出口,使用指定导航链接

    1. import React from 'react'
    2. import {Routes,Route} from 'react-router-dom'
    3. import Login from './pages/Login'
    4. import Register from './pages/Register'
    5. import Home from './pages/Home'
    6. export default function App() {
    7.  return (
    8.   <Routes>
    9.     <Route path='/login' element={<Login/>}>Route>
    10.     <Route path='/register' element={<Register/>}>Route>
    11.     <Route path='/' element={<Home/>}>Route>
    12.   Routes>
    13. )
    14. }

    核心组件作用说明

    • Routes:提供一个路由出口,满足条件的路由组件会渲染到组件内部

    • Route: 用于指定导航链接,完成路由跳转

      • path:path属性指定匹配的路径地址

      • element element属性指定要渲染的组件

    三、路由跳转

    React Router 中,路由的跳转分为两种方式:

    • 标签(组件)跳转

    • JS(API)跳转

    1、通过Link组件跳转
    1. import React from 'react'
    2. import {Link} from 'react-router-dom'
    3. export default function Login() {
    4.  return (
    5.    <div>
    6.        <h1>用户登录h1>
    7.        <Link to="/register">没有账号,去注册Link>
    8.    div>
    9. )
    10. }
    2、编程式路由跳转

    实现步骤

    • 导入useNavigate钩子函数

    import {useNavigate} from 'react-router-dom'
    • 执行钩子函数得到跳转函数

     let navigate=useNavigate();
    • 执行跳转函数完成跳转

    1. import React from 'react'
    2. import {useNavigate} from 'react-router-dom'
    3. export default function Register() {
    4.  const navigate=useNavigate()
    5.  const register=(e)=>{
    6.    e.preventDefault()
    7.    navigate('/login')
    8. }
    9.  return (
    10.    <div>
    11.        <h1>用户注册h1>
    12.        <a href="#" onClick={(e)=>{register(e)}}>已注册,去登录a>
    13.    div>
    14. )
    15. }

    注意

    • 如果在跳转时不想加历史记录,可以添加额外参数replace为true

    1. const register=(e)=>{
    2.    e.preventDefault()
    3.    navigate('/login',{replace:true})
    4. }

    四、嵌套路由

    1、基础配置

    实现步骤

    • 定义嵌套路由声明

    1. <Routes>
    2. <Route path='/login' element={<Login/>}>Route>
    3. <Route path='/register' element={<Register/>}>Route>
    4. <Route path='/' element={<Home/>}>
    5. <Route path='category' element={<Category/>}>Route>
    6. <Route path='goods' element={<Goods/>}>Route>
    7. Route>
    8. Routes>
    • 设置二级路由出口

    1. export default function Home() {
    2. return (
    3. <>
    4. <aside>
    5. <ul>
    6. <li><NavLink to="/categroy">分类管理NavLink>li>
    7. <li><NavLink to="/goods">商品管理NavLink>li>
    8. ul>
    9. aside>
    10. <section>
    11. {/* 二级路由出口 */}
    12. <Outlet>Outlet>
    13. section>
    14. )
    15. }
    2、默认二级路由设置
    1. <Routes>
    2. <Route path='/login' element={<Login/>}>Route>
    3. <Route path='/register' element={<Register/>}>Route>
    4. <Route path='/' element={<Home/>}>
    5. {/*默认二级路由,添加index属性,删除掉path属性*/}
    6. <Route index element={<Main/>}>Route>
    7. <Route path='category' element={<Category/>}>Route>
    8. <Route path='goods' element={<Goods/>}>Route>
    9. Route>
    10. Routes>
    3、404页配置

    应用场景:当所有的路径都没有匹配的时候显示

    语法说明:在各级路由的最后添加*号路由作为兜底

    1. <Routes>
    2. <Route path='/login' element={<Login/>}>Route>
    3. <Route path='/register' element={<Register/>}>Route>
    4. <Route path='/' element={<Home/>}>
    5. {/*默认二级路由,添加index属性,删除掉path属性*/}
    6. <Route index element={<Main/>}>Route>
    7. <Route path='category' element={<Category/>}>Route>
    8. <Route path='goods' element={<Goods/>}>Route>
    9. Route>
    10. {/*当所有路径都没有匹配时渲染此路由*/}
    11. <Route path='*' element={<NotFound/>}>Route>
    12. Routes>

    五、路由模式

    BrowserRouter模式部署在Nginx服务器上出现404问题的解决办法

    1、React打包
    • 在index.js的上添加basename属性,比如

    1. <BrowserRouter basename='/crem'>
    2. <App>App>
    3. BrowserRouter>
    • 在package.json中添加"homepage": "."

    1. {
    2. "homepage": "."
    3. }
    • 在终端上执行打包命令

    yarn build
    2、Nginx上部署
    • 打包后会产生一个build文件夹,然后将该文件改名为crem,

    • 上传文件的linux服务器的/opt目录下

    • 在/etc/nginx/conf.d/default.conf下添加如下配置

    1. location /crem {
    2. alias /opt/crem;
    3. index index.html;
    4. }
    • 进入shell中执行如下命令

    1. ps aux|grep nginx #查看nginx进程
    2. killall -9 nginx #杀死nginx进程
    3. /usr/sbin/nginx #启动nginx服务器
    3、防止404的配置
    • 修改/etc/nginx/conf.d/default.conf文件,添加如下配置即可

    1. location /crem {
    2. alias /opt/crem;
    3. index index.html;
    4. try_files $uri /crem/index.html;
    5. }

    六、路由传参

    1、searchParams传参

    实现步骤

    • 传参

    1. import {useNavigate} from 'react-router-dom'
    2. export default function CategroyList() {
    3. let navigate=useNavigate();
    4. return (
    5. <div>
    6. <h2>CategroyListh2>
    7. <button onClick={()=>{navigate('/categroyDetail?id=12')}}>详情button>
    8. div>
    9. )
    10. }
    • 获取参数

    1. import {useSearchParams} from 'react-router-dom'
    2. export default function CategoryDetail() {
    3. let [params]=useSearchParams()
    4. return (
    5. <div>
    6. <h2>CategroyDetailh2>
    7. <div>
    8. ID:{params.get('id')}
    9. div>
    10. div>
    11. )
    12. }
    2、params传参

    实现步骤

    • 路由设置

    1. <BrowserRouter>
    2. <Routes>
    3. <Route path='/home' element={<Layout/>}>
    4. <Route path='categroy-detail/:id' element={<CategoryDetail/>}>Route>
    5. Route>
    6. Routes>
    7. BrowserRouter>
    • 传参

    1. import {useNavigate} from 'react-router-dom'
    2. export default function CategroyList() {
    3. let navigate=useNavigate();
    4. return (
    5. <div>
    6. <h2>CategroyListh2>
    7. <button onClick={()=>{navigate('/home/categroy-detail/13')}}>详情button>
    8. div>
    9. )
    10. }
    • 获取参数

    1. import React from 'react'
    2. import {useParams} from 'react-router-dom'
    3. export default function CategoryDetail() {
    4. let params=useParams()
    5. return (
    6. <div>
    7. <h2>CategroyDetailh2>
    8. <div>
    9. ID:{params.id}
    10. div>
    11. div>
    12. )
    13. }

    七、集中式路由渲染

    实现步骤

    • 在项目根目录创建router文件夹,并在该目录下创建index.jsx

    • 在router/index.jsx编写路由配置项

    1. import Login from '../pages/Login'
    2. import Register from '../pages/Register'
    3. import Home from '../pages/Home'
    4. import CategoryList from '../pages/Category'
    5. import CategoryDetail from '../pages/Category/Detail'
    6. import GoodsList from '../pages/Goods'
    7. import Main from '../pages/Home/Main'
    8. export default [
    9. {
    10. path:'/login',
    11. element:<Login/>
    12. },
    13. {
    14. path:'/register',
    15. element:<Register/>
    16. },
    17. {
    18. path:'/',
    19. element:<Home/>,
    20. children:[
    21. {
    22. index:true,
    23. element:<Main/>
    24. },
    25. {
    26. path:'/categoryList',
    27. element:<CategoryList/>
    28. },
    29. {
    30. path:'/categoryDetail/:id',
    31. element:<CategoryDetail/>
    32. },
    33. {
    34. path:'/goodsList',
    35. element:<GoodsList/>
    36. }
    37. ]
    38. }
    39. ]
    • 在App.jsx中通过useRoutes钩子函数来进行集中式配置

    1. import {useRoutes} from 'react-router-dom'
    2. import router from './router/index'
    3. function App() {
    4. return useRoutes(router)
    5. }
    6. export default App;
    • 在项目根目录下的index.js中使用包裹

    1. root.render(
    2. <BrowserRouter>
    3. <App/>
    4. BrowserRouter>
    5. )

    八、路由懒加载

    1、实现步骤
    • 使用lazy(()=>import('xxx'))方式导入组件

    1. import {lazy} from 'react'
    2. const Login=lazy(()=>import('../pages/Login'))
    3. const Register=lazy(()=>import('../pages/Register'))
    4. const Home=lazy(()=>import('../pages/Home'))
    5. const CategoryList=lazy(()=>import('../pages/Category'))
    6. const CategoryDetail=lazy(()=>import('../pages/Category/Detail'))
    7. const GoodsList=lazy(()=>import('../pages/Goods'))
    8. const Main=lazy(()=>import('../pages/Home/Main'))
    9. export default [
    10. {
    11. path:'/login',
    12. element:<Login/>
    13. },
    14. {
    15. path:'/register',
    16. element:<Register/>
    17. },
    18. {
    19. path:'/',
    20. element:<Home/>,
    21. children:[
    22. {
    23. index:true,
    24. element:<Main/>
    25. },
    26. {
    27. path:'/categoryList',
    28. element:<CategoryList/>
    29. },
    30. {
    31. path:'/categoryDetail/:id',
    32. element:<CategoryDetail/>
    33. },
    34. {
    35. path:'/goodsList',
    36. element:<GoodsList/>
    37. }
    38. ]
    39. }
    40. ]
    • 通过 React 中提供了 组件,来实现路由的懒加载。

    1. import {Suspense} from 'react'
    2. function App() {
    3. return(
    4. <Suspense fallback={<>loading}>
    5. {useRoutes(router)}
    6. Suspense>
    7. )
    8. }

    组件身上,必须设置一个 fallback 属性,属性值可以是一个 HTML 标签,也可以是一个自定义的组件。用于当路由组件还未加载出来前的提示。

    2、解决路由闪屏

    配置完路由懒加载后出现当进行路由跳转时,出现闪屏现象,要向解决这个问题可以使用 react-loadable插件进行解决

    • 先下载react-loadable依赖包

    yarn add react-loadable
    • 建立一个loadable.js,放在src/utils/loadable.js

    1. import Loadable from 'react-loadable';
    2. export default function withLoadable(comp) {
    3. return Loadable({
    4. //懒加载组件页面
    5. loader: comp,
    6. loading: () => null,
    7. delay: "",
    8. })
    9. }
    • 修改router/index.js

    1. import loadable from '../utils/loadable'
    2. const Login=loadable(()=>import('../pages/Login'))
    3. const Register=loadable(()=>import('../pages/Register'))
    4. const Home=loadable(()=>import('../pages/Home'))
    5. const CategoryList=loadable(()=>import('../pages/Category'))
    6. const CategoryDetail=loadable(()=>import('../pages/Category/Detail'))
    7. const GoodsList=loadable(()=>import('../pages/Goods'))
    8. const Main=loadable(()=>import('../pages/Home/Main'))
    9. export default [
    10. {
    11. path:'/login',
    12. element:<Login/>
    13. },
    14. {
    15. path:'/register',
    16. element:<Register/>
    17. },
    18. {
    19. path:'/',
    20. element:<Home/>,
    21. children:[
    22. {
    23. index:true,
    24. element:<Main/>
    25. },
    26. {
    27. path:'/categoryList',
    28. element:<CategoryList/>
    29. },
    30. {
    31. path:'/categoryDetail/:id',
    32. element:<CategoryDetail/>
    33. },
    34. {
    35. path:'/goodsList',
    36. element:<GoodsList/>
    37. }
    38. ]
    39. }
    40. ]
  • 相关阅读:
    机器学习 l2正则化--岭回归
    MySQL 深分页优化
    【C语言】23-结构体类型
    jvm 一之 类加载器
    SpringBoot接收参数的三种方式:
    Go语言用Resty库编写的音频爬虫代码
    `算法知识` 算法代码模板
    SpringBoot文件上传深入浅出
    自学软件测试1个半月上岸拿5个offer
    Obsidian配置
  • 原文地址:https://blog.csdn.net/m0_74343097/article/details/132644539