React 路由配置:useRoutes 的使用详解

在现代前端开发中,路由配置 是构建单页应用(SPA)的重要组成部分。React 中最常用的路由库是 react-router-dom,它帮助我们实现页面之间的跳转和组件的动态加载。 今天我们就来聊一聊 React Router 中的 useRoutes 钩子函数,以及它是如何帮助我们更优雅地配置路由的。


一、传统路由配置方式(使用 JSX)

在 React Router 中,最基础的路由配置方式是通过 <BrowserRouter><Routes> + <Route> 来完成的。例如:

jsx 复制代码
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import Login from './Pages/Login'
import NoteClass from './Pages/NoteClass'

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Navigate to="/noteClass" />} />
        <Route path="/login" element={<Login />} />
        <Route path="/noteClass" element={<NoteClass />} />
      </Routes>
    </BrowserRouter>
  )
}

这种方式虽然直观,但当路由很多时,维护起来会变得不太方便,尤其是想动态生成路由集中管理路由配置时,就显得不够灵活。


二、useRoutes:用 JS 对象配置路由(更灵活的方式)

React Router v6+ 提供了一个非常好用的钩子函数:useRoutes,它允许我们使用 JavaScript 对象的方式来定义路由规则,非常适合大型项目或需要动态配置路由的场景。

✅ 使用步骤如下:

1. 引入组件(使用懒加载)

为了提升性能,我们通常会使用 React.lazy() 来实现组件的懒加载,即只有在访问对应路由时才加载组件。如果不使用懒加载,用户打开网页时,会一次性加载所有页面的代码,哪怕他只看首页。用了懒加载之后,只有用户访问某个页面时,才会加载那个页面的组件,这样首页加载更快,用户体验更好。

js 复制代码
import React from 'react'

const Login = React.lazy(() => import('../Pages/Login'))
const NoteClass = React.lazy(() => import('../Pages/NoteClass'))

⚠️ 每个懒加载的组件都要单独引入。


2. 定义路由配置对象

接下来,我们定义一个 routes 数组,里面是每个路由的配置对象:

js 复制代码
const routes = [
  {
    path: '/',
    element: <Navigate to="/noteClass" /> // 默认重定向到 /noteClass
  },
  {
    path: '/login',
    element: <Login /> // 登录页面
  },
  {
    path: '/noteClass',
    element: <NoteClass /> // 主页
  }
]

这里用到了 <Navigate> 组件,它是 React Router v6+ 提供的重定向组件,用于将用户从一个路径跳转到另一个路径。如果你没有指定要访问哪个页面,那就自动跳转到 /noteClass


3. 创建一个封装了 useRoutes 的组件

我们创建一个 WrapperRoutes 函数组件,用来调用 useRoutes 并返回对应的路由元素:

js 复制代码
import { useRoutes } from 'react-router-dom'

function WrapperRoutes() {
  const ele = useRoutes(routes)
  return ele
}

但注意:useRoutes 必须在路由上下文中使用 ,也就是说它必须包裹在 <BrowserRouter> 里面。


4. 包裹在 BrowserRouter 中

为了解决上下文的问题,我们再创建一个 WrapperRouter 组件,把 WrapperRoutes 包裹在 <BrowserRouter> 中:

js 复制代码
import { BrowserRouter } from 'react-router-dom'

export default function WrapperRouter() {
  return (
    <BrowserRouter>
      <WrapperRoutes />
    </BrowserRouter>
  )
}

三、最终使用方式

现在,我们可以在主组件 App.jsx 中直接使用这个封装好的路由组件:

jsx 复制代码
import React from 'react'
import WrapperRouter from './router'
import toast, { Toaster } from 'react-hot-toast'

export default function App() {
  return (
    <>
      <WrapperRouter />
      <Toaster />
    </>
  )
}

这样,我们就完成了整个路由的配置。

四、使用扩展

现在如果想把所有和用户相关的页面路径都统一放在 /user/xxx 这样的结构下,比如:

  • 用户首页:/user/home
  • 用户资料:/user/profile
  • 用户设置:/user/settings

那我们就要对原来的路由结构做一些调整,让这些路径都统一归类到 /user/

js 复制代码
const routes = [
  {
    path: '/',
    element: <Navigate to="/user/home" />
  },
  {
    path: '/login',
    element: <Login />
  },
  {
    path: '/user',
    children: [
      {
        index: true,
        element: <Navigate to="home" />
      },
      {
        path: 'home',
        element: <UserHome />
      },
      {
        path: 'profile',
        element: <UserProfile />
      },
      {
        path: 'settings',
        element: <UserSettings />
      }
    ]
  }
]

children 里的路径是"子路径",它们会自动继承父路径 /user。所以当用户访问 /user 时,会自动跳转到 /user/home

相关推荐
计算机魔术师1 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1281 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师1 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen2 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒2 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
wangchunyu1143 小时前
JavaScript 零基础入门教程
前端
hanchenxing3 小时前
前端异步任务三方案:Celery vs Redis Stream vs BullMQ 实战对比消息队列
前端·数据库·redis·异步任务·方案对比
mONESY3 小时前
LangGraph.js 从零上手:把 Agent 工作流从一条线变成一张网
javascript
默_笙3 小时前
⚓ AI 的"官方答题卡":withStructuredOutput 与结构化输出的终局之战
前端·javascript
掘金挖土3 小时前
前端手摸手跑路之 AI 应用开发(五)
前端·后端