Skip to Content
🎉 Nextra 4.0 is released. dimaMachina is looking for a new job or consulting.
路由useRoute

useRoute

useRoute 是对 React Router 的一个自定义封装,用于获取当前路由的相关信息并进行处理与扩展。它除了返回最后一个匹配的路由的常规属性,还包含对查询参数 (query)、散列值 (hash)、完整路径 (fullPath)、错误信息 (error) 等的便捷获取,同时对动态路由参数 (params) 进行了特殊处理(如 [...slug] 转换成字符串数组)。

函数签名

export function useRoute< T = unknown, Q extends Record<string, string> | null = Record<string, string>, P extends Record<string, string | string[]> = Record<string, string | string[]> >(): Router.Route<T, Q, P>

泛型参数

  • T: 路由数据类型 代表当前路由在 loader / clientLoader 中返回的 data 类型。默认为 unknown
  • Q: 查询参数类型 解析自 location.search 的查询参数对象类型,默认为 Record<string, string>(也可为 null)。
  • P: 路径参数类型 在动态路由匹配(如 :id[...slug])时解析到的 params 类型,默认为 Record<string, string | string[]>
    • 对于 [...slug] 之类的路由,会将 params.slug 转换为 字符串数组
    • 对于普通的 :id,则是单一字符串。

返回值

该 Hook 返回一个扩展后的路由对象,类型为 Router.Route<T, Q, P>,包含以下主要字段:

字段类型说明
dataT通过路由 loader / clientLoader 返回的结果。
handleRouteHandle路由模块中自行定义并导出的 handle 对象。
errorError | null当前路由处理或渲染过程中抛出的错误对象,如果无错误则为 null
fullPathstring当前完整的 URL 路径,包含 pathname + search + hash
hashstringlocation.hash 的值(如 #section-1)。
matchedUIMatch<T, RouteHandle>[]已匹配到的所有路由对象集合(大多情况下,第 0 个为根布局,业务路由从第 1 项开始)。
paramsP (默认为 Record<string, string | string[]>)动态路径参数,特殊情况如 [...slug] 会被解析为字符串数组。
pathnamestringlocation.pathname(如 /blog/123)。
queryQ (默认为 Record<string, string> | null)解析自 location.search 的查询参数对象(如 ?page=1 解析为 { page: '1' })。
searchstringlocation.search(如 ?page=1)。

提示

  • data 即路由 loader / clientLoader 函数返回的值(或者是通过其他方式挂载到路由的异步数据)。
  • handle 是在定义路由时,自行在路由模块中导出的对象,可用于存放自定义的元信息、函数等。

核心逻辑说明

  1. 路由匹配与取值
    • 通过 React Router 提供的 useMatches 获取当前所有匹配路由,并以 matches.at(-1) 作为当前活跃路由信息来源。
  2. 获取基础信息
    • 调用 useLocation() 获得 hash, pathname, search,拼接成 fullPath
  3. 解析查询参数
    • 使用自定义函数(如 parseQuery)将 search 解析为对象,赋给 query
  4. 获取错误
    • 调用 useRouteError() 获得当前路由报错(若有),存入 error
  5. 自定义 params
    • 如果路由包含 catch-all 动态参数 [...slug],会将 params['*'] 拆分为字符串数组,如 params.slug = ['abc','def']
  6. useMemo 缓存
    • 仅在依赖(如 fullPath)变化时,才重新计算并返回路由对象。

使用示例

import React from 'react'; import { useRoute } from '@/hooks/useRoute'; // 定义泛型 T = PostData, Q = { page: string }, P = { slug: string[] } function PostDetail() { const { data, handle, error, params, query, pathname, fullPath } = useRoute<PostData, { page: string }, { slug: string[] }>(); if (error) { return <div>Error: {error.message}</div>; } return ( <div> <h2>Post Detail</h2> <p>Handle: {JSON.stringify(handle)}</p> <p>Data from loader: {JSON.stringify(data)}</p> <p>Params: {JSON.stringify(params)}</p> <p>Query: {JSON.stringify(query)}</p> <p>Pathname: {pathname}</p> <p>FullPath: {fullPath}</p> </div> ); } export const loader = async ({ params }: { params: { slug: string[] } }) => { return { data: { slug: params.slug } } }
  • 如果当前路由为 /post/abc/def?page=2 且路由定义为 [...slug]
    • params.slug => ['abc', 'def']
    • query => { page: '2' }
    • pathname => /post/abc/def
    • fullPath => /post/abc/def?page=2
    • 如果在路由模块中导出了 handle,可在此处通过 handle 获取。

通过 useRoute,你可在业务组件中一站式获取到解析后的路由信息,省去频繁在多个 Hook 间切换的麻烦,并自动处理多段参数等特殊场景,让开发更高效、代码更整洁。

Last updated on