
Refine v5 useGo Hook 深度指南资源路由、查询参数与导航类型全解析【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineuseGo是 Refine v5 中统一路由导航的核心 Hook它直接封装了routerProvider的go方法让你既能按路径跳转也能按resource对象跳转。本文将以官方文档为主体结合refinedev/core的源码实现与测试用例完整讲解useGo的用法、全部参数语义、返回类型以及它在多租户嵌套路由、查询参数合并等真实场景中的工作细节。读完本文你将能熟练使用useGo完成 React 管理后台中几乎所有的导航需求并理解其底层调用链。useGo 是什么useGo是一个用于执行导航操作的 Hook它本质上是routerProvider中go方法的便捷入口。Refine 将路由库React Router、Next.js Router、Remix Router 等抽象为统一的routerProvider接口而useGo让业务组件无需关心底层路由库的差异直接用统一的配置对象完成导航。在 router 上下文类型定义 中go接受的配置类型为export type GoConfig { to?: string; query?: Recordstring, unknown; hash?: string; options?: { keepQuery?: boolean; keepHash?: boolean; }; type?: push | replace | path; };其接口约定为GoFunction (config: GoConfig) void | string即除了type: path会返回路径字符串外其余情况不返回值。基础用法按路径导航useGo最直接的使用方式是传入一个路径字符串作为to。以下示例在点击按钮时携带一组过滤条件跳转到/posts页面import { useGo } from refinedev/core; const MyComponent () { const go useGo(); return ( Button onClick{() { go({ to: /posts, query: { filters: [ { field: title, operator: contains, value: Refine, }, ], }, type: push, }); }} Go Posts With Default Filters /Button ); };这里query中的filters数组会被routerProvider序列化为查询字符串不同路由库实现细节略有差异后文会结合源码说明从而实现带默认筛选进入列表页的典型管理后台场景。按资源导航to传对象除了路径字符串to还支持传入一个资源对象由useGo根据Refine /中resources数组里定义的路径模板自动转换为实际路径。官方文档给出的对象结构如下type ToWithResource { resource: string; // resource name or identifier id?: BaseKey; // required when action is edit, show, or clone. action: list | create | edit | show | clone; // action name meta?: Recordstring, unknown; // meta data to be used when composing the path (use if you have additional path parameters) };其中BaseKey在 interface-references 文档 中的定义为type BaseKey string | number。示例跳转到posts资源的编辑页并附带查询参数import { useGo } from refinedev/core; const MyComponent () { const go useGo(); return ( Button onClick{() { go({ to: { resource: posts, // resource name or identifier action: edit, id: 1, }, query: { foo: bar, }, type: push, }); }} Go Posts With Default Filters /Button ); };资源对象内部如何匹配在 useGo 的实现 中to为对象时会依次执行通过useResourceParams的resourceSelect(config.to.resource)在resources中查找资源调用handleResourceErrors做参数校验调用useGetToPath根据资源、动作、meta含id组合出最终路径把组合好的路径回传给routerProvider的go执行导航。资源对象类型在源码中被细分为两种use-go/index.tsxtype ResourceWithoutId { resource: string; action: ExtractAction, create | list; id?: never; meta?: Recordstring, unknown; }; type ResourceWithId { resource: string; action: ExtractAction, edit | show | clone; id: BaseKey; meta?: Recordstring, unknown; };可以看到类型系统本身已经约束了create/list不需要id而edit/show/clone必须提供id。通过 identifier 引用资源resource字段除了资源名name外还支持资源的identifier。当同一资源被多次注册例如多租户场景下为不同标识注册同一资源时用identifier可以精确命中。测试用例 use-go/index.spec.tsx 验证了resource: id-posts能正确解析到identifier为id-posts的资源并生成/id-posts、/id-posts/1/edit等路径。meta 与嵌套路由meta用于补充路径模板中的额外参数。在多租户或嵌套路由场景中资源路径可能包含动态段例如edit: /:tenantId/posts/:id/edit。测试用例验证了三种取参来源资源级 meta资源定义meta: { tenantId: foo }时go({ to: { resource: posts, action: edit, id: 123 } })生成/foo/posts/123/editspec 用例路由参数当前路由已包含tenantId参数时routerProvider.parse返回的params会被自动利用spec 用例to.meta在to.meta: { tenantId: foo }中显式传入spec 用例。这些参数最终由 useGetToPath 实现 调用composeRoute(actionRoute, fullResource?.meta, parsed, meta)完成路径填充优先级顺序为当前路由参数 资源 meta 本次传入的 meta。参数详解toto是目标路径。如果留空则导航到当前路径——此时配合query使用非常适合只更新查询参数的场景例如刷新列表页的筛选条件。此外也可以传入上文介绍的resource对象由routerProvider转换为路径。从 react-router 绑定实现 可以看到to为undefined时最终生成的urlTo为空字符串此时fullPath仅由查询串与 hash 构成从而实现在当前页面原地更新 URL。queryquery是希望附加到路径上的查询参数对象routerProvider会将其转换为查询字符串。在 React Router 的实现 中序列化使用qs库并配置为export const stringifyConfig { addQueryPrefix: true, skipNulls: true, arrayFormat: indices as const, encode: false, encodeValuesOnly: true, };addQueryPrefix: true结果以?开头skipNulls: true值为null的键会被忽略arrayFormat: indices数组以filters[0][field]title形式序列化这正是 Refine 的filters对象能被还原的关键encode: false/encodeValuesOnly: true仅对值做编码。这也是为什么query中可以直接放filters、sorters这类结构化对象——它们与routerProvider.parse的反序列化逻辑是对称设计的。typetype指定导航类型共有三种push向历史栈新增一条记录用户可后退replace替换当前历史记录用户无法后退到当前页path只返回根据配置计算出的导航路径不修改历史栈、不触发跳转。适用于生成链接、重定向目标等只算不用的场景。在 react-router 绑定中bindings.tsxtype path时直接return fullPath否则调用navigate(fullPath, { replace: type replace })。hashhash是要附加到路径上的 hash锚点例如go({ to: /posts, hash: comments })会生成/posts#comments。在 bindings.tsx 中最终 hash 由三部分决定显式传入的hash、keepHash保留的现有 hash、默认空——且会去除前导#后统一重新拼接因此传入#comments或comments效果一致。options.keepQueryoptions.keepQuery是布尔值决定是否保留当前查询参数true当前查询参数与新的query合并相同键由新值覆盖false默认忽略当前查询参数仅使用本次传入的query。react-router 实现中的合并逻辑bindings.tsx为const urlQuery { ...(keepQuery existingSearch qs.parse(existingSearch, { ignoreQueryPrefix: true, depth: QS_PARSE_DEPTH, })), ...query, };注意keepQuery为true时会浅合并即query中的键覆盖同名旧值其余旧参数保留。另外源码中有一个细节若合并后结果中存在to键会被encodeURIComponent编码bindings.tsx用于避免重定向地址类参数被破坏。options.keepHashoptions.keepHash是布尔值决定是否保留当前 hashtrue当前 hash 会保留在 URL 中false默认忽略当前 hash。实现逻辑见 bindings.tsxurlHash \#${(hash || (keepHash existingHash) || ).replace(/^#/, )}。当显式传入hash时hash优先于keepHash。返回值useGo本身不返回数据唯一例外是type: path此时返回根据配置计算出的导航路径字符串且不会修改历史栈。这在实现Link、预计算跳转地址等场景中非常有用。事实上Refine 的Link组件 正是依赖这一点实现的当传入go属性时它会以type: path调用useGo计算出resolvedTo再交给routerProvider.Link或原生a渲染从而保证链接与useGo的路径生成逻辑完全一致。源码级原理useGo 的完整调用链把官方文档的用法与源码对应起来一次典型的按资源导航调用链如下取go函数useGo从RouterContext中取出routerContext.go并立即调用它go被设计为返回函数的函数生成器便于在函数内部使用 React Hooks得到真正的导航函数goFromRouter。若上下文不存在则回退为空操作use-go/index.tsx分流处理config.to为字符串时直接透传给goFromRouter为对象时走资源解析分支资源解析resourceSelect(config.to.resource)定位资源项随后handleResourceErrors做三项校验路径组合getToPath({ resource, action, meta: { id, ...config.to.meta } })通过useGetToPath找到该资源对应 action 的路由模板并调用composeRoute填充动态参数执行导航将组合后的to与原query、hash、type、options一并交给goFromRouter。handleResourceErrors三条错误约定handleResourceErrorsuse-go/index.tsx会在导航前抛出三类错误帮助尽早发现配置问题[useGo]: action or resource is required.——to对象缺少action或resource[useGo]: [action: edit] requires an id for resource [resource: posts]——edit/show/clone动作未传id[useGo]: [action: list] is not defined for [resource: users]—— 资源未定义该 action 的路径模板。对应测试见 use-go/index.spec.tsx 与 handleResourceErrors 测试。useGetToPath 的资源匹配策略useGetToPath 在从resources中获取完整资源定义时匹配优先级为identifier与选中资源的identifier一致资源的identifier等于选中资源的namename完全一致兜底使用传入的资源对象本身。找不到对应 action 路由时会通过warnOnce输出警告并返回undefineduse-get-to-path/index.ts。路由库侧的最终落地在 React Router 的go实现 中go返回的函数内部通过useLocation读取当前search与hash用useNavigate执行跳转并完成查询参数合并、to编码、hash 拼接、type path提前返回等全部细节。这也解释了为什么useGo能跨 React Router / Next.js / Remix 等不同路由库保持一致的调用体验——差异全部封装在routerProvider内。测试验证规范即契约useGo的测试覆盖在 use-go/index.spec.tsx 中非常完整可作为理解其行为边界的参考测试场景预期行为返回routerProvider的go函数配置对象原样传递给 mockGo含hash、options、query、to、typego未定义 / 在 RouterProvider 外使用返回undefined不抛错五种 action 的路径解析list → /posts、create → /posts/create、edit → /posts/1/edit、show → /posts/1、clone → /posts/1/clone按identifier导航正确解析到identifier: id-posts的注册资源资源未定义 / action 缺失抛出[useGo]前缀的明确错误meta、资源级 meta、路由参数均能填充:tenantId等动态段这些用例既验证了资源对象转路径的核心能力也固化了错误信息文本与合并策略方便你在升级或自定义routerProvider时对照排查。与其他导航 API 的关系与useGetToPathuseGetToPath只负责算路径resource action meta → path不执行跳转而useGo在此基础上叠加了query、hash、type、keepQuery/keepHash的完整导航能力并按需调用routerProvider.go。相关文档见 use-get-to-path 文档与Link组件Link支持go属性内部以type: path复用useGo生成 href保证链接地址与编程式导航一致与useNavigationuseNavigation是封装useGo的遗留 Hook见 useNavigation 源码虽然未标记废弃但不推荐新代码使用。官方建议自定义导航时优先用路由库原生 Hooks在需要按资源/动作导航时使用useGo与useGetToPath参见 useNavigation 文档。小结useGo是 Refine v5 路由体系中一处声明、处处可用的导航入口to支持路径字符串与资源对象两种形态query/hash/options提供查询参数与锚点的精细控制type的push/replace/path三种模式覆盖了跳转、替换与仅计算路径的全部需求。结合routerProvider的抽象与useGetToPath的路径组合机制它能够让管理后台的导航代码与具体路由库解耦同时在多租户、嵌套路由等复杂路径模板下保持正确与可预测。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考