Refine v5 路由迁移指南:从routerProvider3.x 到 4.x 的全面升级实践
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
导读
本文以 Refine 官方迁移文档为主体,系统讲解从 Refine v3.x 的routerProvider(路由提供器)迁移到 v4.x/v5 新式路由绑定的全过程:包括变更动机、<Refine>组件 props 的废弃、认证与权限控制的职责转移、以及 React Router v6 / Remix / Next.js 三种主流路由方案的实操接入方式。读完本文,你将掌握新路由架构下的useLink、useGo、useBack、useParsed四个核心 hook,能够在不改造成本项目既有路由结构的前提下,将 Refine 无缝集成进现有应用。
变更动机:把路由交还给开发者
Refine 对routerProvider和路由处理的改造,核心动机是提升灵活性与易用性。官方文档明确指出:通过把routerProvider简化为 Refine 与路由器之间的“交互与连接点”,Refine 不再规定定义路由的特定方式,也不再强制要求必须传入routerProvider——这使 Refine 能够满足企业级应用的多样化需求。
这一设计取向在源码中得到了直接印证。路由绑定类型定义 中,RouterProvider的四个成员go、back、parse、Link全部被标记为可选,并附有一段关键的实现注释:
我们将这些函数定义为可选,某些功能可能无法正常工作,但这是有意的。用户可以选择使用路由绑定,也可以不使用,或者使用自己的路由绑定。把控制权留给用户是最佳方式。
这解释了为什么此次迁移的核心收益是:你可以在不修改当前路由或应用结构的情况下,将 Refine 集成进现有项目——继续像以前一样使用路由器,同时享受 Refine 提供的数据、表单、表格等能力。
重要注意事项:迁移前必须知道的三件事
1. 认证检查不再由路由接管
使用新版routerProvider后,路由层不再内置认证拦截。如果应用使用了authProvider,你需要自行负责认证检查,官方推荐两种方式:
useIsAuthenticatedhook(命令式)Authenticated组件(声明式包装器)
具体实现示例可在 Authenticated 组件文档 和各示例应用中查看。
2. 访问控制检查同样需要自行处理
与认证流程类似,路由内部不再处理权限控制。你需要使用useCanhook 或CanAccess组件自行完成,可参考 CanAccess 组件文档。
3. 路由的创建与控制完全交由用户
你必须手动创建路由;如果希望资源操作(create/edit/list/show 等)使用特定路径,可以将路径传入resources数组中对应 action。文档中虽然提供了从资源生成路由的方法,但它们是可选的,且不推荐使用,因为这会限制灵活性。
<Refine>组件的 props 变化
由于路由处理已从<Refine>组件中解耦,组件接受的 props 也随之改变:
- 已废弃且不再生效的布局类 props:
Layout、Sider、Title、Header、Footer、OffLayoutArea。不过,UI 包导出的这些组件仍然受到良好支持,你可以在创建路由和页面时在应用内部使用它们。 - 同样废弃的组件 props:
DashboardPage、catchAll、LoginPage。你需要自己创建对应的路由和页面来替代。
旧版行为提示(Dashboard 页面)
由于
DashboardPageprop 已废弃,你需要为 dashboard 创建自己的 index 路由。可以将该项加入resources数组使其出现在<Sider>菜单中——useMenu会根据resources数组生成菜单项;你也可以用useMenuhook 自行定制菜单。
错误页面和登录页面同理:用你的路由器所适配的方式自行创建,替代原先catchAll和LoginPageprops 的职责。
自定义<Sider>组件的迁移
如果你曾从 UI 包 swizzle 出<Sider>组件并做过定制,在使用新的routerProviderprop 时可能需要同步更新。
更新useRouterContext的使用
新版routerProvider引入后,v3 兼容的路由提供器改由legacyRouterProviderprop 提供:
- 如果使用
legacyRouterProvider,useRouterContext会继续照常工作; - 如果使用新版
routerProvider,useRouterContext对你而言已废弃且无用,可以轻松替换为useLink、useGo、useBack、useParsed这四个路由 hook。
在<Sider>组件中,Refine 曾通过useRouterContext获取Link组件。迁移时既可以改用useLinkhook,也可以直接切换到路由器自身的Link实现(如react-router-dom的Link或next/link):
- import { useRouterContext } from "@refinedev/core"; + import { useLink } from "@refinedev/core"; const CustomSider = () => { - const { Link } = useRouterContext(); + const Link = useLink(); /* ... */ }注意:如果你定制过
useMenuhook 的使用方式,请检查其表现是否符合预期。虽然useMenu的返回值没有改变,但它生成菜单项 key 的方式已经变化。
路由行为的变更
由于 Refine 不再内部创建路由,你可以不受任何限制地按照自己的框架创建路由。authentication与access control从 Refine 中解耦,应按照你的框架惯例处理。同时,Refine 提供了一组辅助工具让这些任务更易完成:
Authenticated组件(作为包装器)或useIsAuthenticatedhook —— 用于认证CanAccess组件(作为包装器)或useCanhook —— 用于访问控制
新路由提供器的底层原理
要理解迁移后的使用方式,有必要先看清新版routerProvider的契约。核心类型定义在 packages/core/src/contexts/router/types.ts:
| 成员 | 签名 | 职责 |
|---|---|---|
go | () => GoFunction | 导航到指定路由,接收GoConfig(含to、query、hash、type、keepQuery/keepHash选项) |
back | () => BackFunction | 返回上一路由,无参数;缺失时 UI 包可能隐藏返回按钮 |
parse | () => ParseFunction | 解析当前路由、查询参数,引导 Refine 识别出正确的resource、action、id及params |
Link | React.ComponentType | 渲染内部链接的组件 |
其中GoConfig.type支持"push" | "replace" | "path"三种模式——"path"模式仅返回拼接好的路径字符串而不执行导航,这在需要"只构造链接"的场景下非常实用。
以 React Router v6 绑定为例,bindings.tsx 展示了每个成员的典型实现:
go:从useLocation读取现有search与hash,通过qs合并查询参数(支持keepQuery/keepHash),最终调用useNavigate执行导航;back:直接映射为navigate(-1);parse:调用matchResourceFromRoute(pathname, resources)从当前路径匹配出resource与action,再合并useParams与 query string,并将currentPage、pageSize数值化、id解码,最终输出结构完整的ParseResponse。
四个新 hook:从useNavigation到细分职责
类型注释中说明了一个关键设计转变:"不再使用单一的useNavigationhook,我们将这些函数拆分为三个不同的 hook:useGo、useBack和useParsed"(连同useLink共四个)。它们的实现位于 packages/core/src/hooks/router:
- useGo:在
go之上增加了"按资源导航"的能力。当config.to传入{ resource, action, id, meta }对象时,会通过useGetToPath自动计算出资源操作对应的真实路径;若该action未在资源上定义、或edit/show/clone缺少id,会抛出带明确提示的错误。 - useBack:从
RouterContext取出back函数,供返回按钮使用。 - useParsed:用
useMemo缓存parse()的结果,返回当前路由解析出的{ resource, action, id, params, pathname }。 - useLink:返回全局
Link组件,使自定义 Sider 等内部组件无需感知具体路由器实现。
误用检测:checkRouterPropMisuse
新版架构还内置了防呆机制。check-router-prop-misuse 会检查routerProviderprop 中除go、parse、back、Link之外的属性:一旦发现存在其他属性(典型场景是把 v3 风格的routes等旧配置塞进新 prop),会console.warn提示"你可能想使用legacyRouterProviderprop 替代"。这能帮助迁移过程中的开发者快速定位问题。
使用新路由提供器:三种主流方案
Refine 为每种提供绑定的路由器都编写了独立文档,以下是最常用的三种。
React Router v6
如果你使用react-router-dom和@refinedev/react-router-v6,需要:
- 使用
Routes、Route、Outlet等组件生成路由; - 用你选定的路由器包裹
<Refine>组件(如<BrowserRouter>); - 从
@refinedev/react-router-v6导入routerProvider传给<Refine>; - 在
resources数组中为资源操作指定路径。
⚠️ 已知问题:partial segments(部分分段)已移除
Refine 原先依赖
react-router-dom@6.3.0,现已升级到react-router-dom@latest。由于6.5.0版本移除了 partial segment 支持,你自定义路由中形如profile/@:username/:page的写法将无法按预期工作,需要按如下方式更新:<Refine - routerProvider={{ - ...routerProvider, - routes: [ - { - element: <ProfilePage />, - path: "profile/@:username/:page", }, ], }} + routerProvider={routerProvider} > + <Route path="profile/:username/:page" element={<ProfilePage />} /> </Refine>- <Link to="profile/@:username/:page" /> + <Link to="profile/:username/:page" />
详细的接入说明可查看@refinedev/react-router-v6包文档 及仓库中的实际示例(如 examples/with-remix-headless 之外的 examples/with-nextjs-headless、examples/base-headless 等基于 React Router 的 headless 示例应用)。
Remix 与 Next.js
如果使用 Remix 或 Next.js,步骤为:
- 首先按照你惯常的方式,使用基于文件系统的路由(file system-based routing)创建路由;
- 将
@refinedev/remix-router或@refinedev/nextjs-router提供的routerProvider传给<Refine>组件; - 在
resources数组中指定资源操作的路径。
仓库中提供了可直接对照的完整示例:examples/with-remix-antd、examples/with-remix-material-ui、examples/with-nextjs、examples/with-nextjs-next-auth 等,均演示了如何在文件系统路由之上接入 Refine 资源。
分别参考:
@refinedev/remix-router与 Remix 官方文档(对应示例见 with-remix-headless)@refinedev/nextjs-router与 Next.js 官方文档(对应示例见 with-nextjs)
迁移检查清单
| 检查项 | 旧方式 | 新方式 |
|---|---|---|
| 路由创建 | Refine 内部根据routes/catchAll等生成 | 完全由你(或你的框架)创建 |
| 认证拦截 | 路由层自动处理 | useIsAuthenticated/Authenticated |
| 访问控制 | 路由层自动处理 | useCan/CanAccess |
| Dashboard | <Refine DashboardPage={...}> | 自建 index 路由 + 加入resources |
| 错误/登录页 | catchAll/LoginPageprops | 自建路由与页面 |
| 布局 props | Layout/Sider/Header/Footer/OffLayoutArea | 废弃,改在路由树中自行组装组件 |
| 获取 Link | useRouterContext().Link | useLink或路由器原生Link |
| 旧版兼容 | — | legacyRouterProvider(v3 绑定继续可用) |
总结
Refine v5 的路由架构将"路由定义权"完整交还给开发者:routerProvider只保留go、back、parse、Link四个轻量绑定点,认证、权限、页面组织全部由你的框架与组件自行掌控;同时通过legacyRouterProvider保证 v3 时代的平滑过渡,用checkRouterPropMisuse帮助开发者识别新旧 prop 混用。迁移路径清晰——按 React Router v6 / Remix / Next.js 三种方案创建路由、替换四个 hook、补充认证与权限检查,即可在保留既有路由结构的前提下完整获得 Refine 的能力。
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考