如何封装可复用路由Hook,根据当前路径和tabs配置返回下一路径
可复用路由下一步跳转Hook实现
封装思路
我们将原有耦合在业务组件里的逻辑抽离为独立Hook,核心调整点:
- 支持外部传入
tabsDetails路由配置,不硬编码在逻辑中 - 支持返回计算好的下一路径供业务自行处理,也可直接调用封装好的跳转方法
- 兼容react-router v5/v6两种常见路由版本的跳转方式
- 补充异常路径兜底逻辑,避免匹配不到路径时的报错
完整Hook代码
// 适配react-router v6 版本,如果你用v5请将useNavigate替换为useHistory,跳转逻辑对应调整即可 import { useLocation, useNavigate } from 'react-router-dom' import { useMemo, useCallback } from 'react' const useNextRoute = (tabsDetails) => { const location = useLocation() const navigate = useNavigate() // v5版本替换为:const history = useHistory() // 提前计算所有路由路径列表,缓存结果避免重复计算 const tabPathList = useMemo(() => { if (!Array.isArray(tabsDetails) || tabsDetails.length === 0) return [] return tabsDetails.map(item => item.path) }, [tabsDetails]) // 计算下一路径 const nextPath = useMemo(() => { if (tabPathList.length === 0) return '' // 拆分当前路径,提取最后一级路由名 const pathSegments = location.pathname.split('/') const lastSegment = pathSegments.at(-1) || '' const currentFullPath = `/${lastSegment}` // 匹配当前路由在配置中的索引 const currentIndex = tabPathList.indexOf(currentFullPath) if (currentIndex === -1) return '' // 计算下一路由索引,模运算实现循环跳转 const nextIndex = (currentIndex + 1) % tabPathList.length const nextFullPath = tabPathList[nextIndex] const nextLastSegment = nextFullPath.split('/').at(-1) || '' // 拼接完整的新路径 const newPathSegments = [...pathSegments] newPathSegments.pop() newPathSegments.push(nextLastSegment) return newPathSegments.join('/') }, [location.pathname, tabPathList]) // 封装跳转方法 const goNextRoute = useCallback(() => { if (nextPath) { navigate(nextPath) // v5版本替换为:history.push(nextPath) } }, [nextPath, navigate]) return { nextPath, goNextRoute } } export default useNextRoute
业务组件使用示例
// 你的业务组件中使用 const tabsDetails = [ { path: "/user-details" }, { path: "/service-details" }, { path: "/previous-experience-details" }, { path: "/documents" }, ] const FormStepPage = () => { const { goNextRoute, nextPath } = useNextRoute(tabsDetails) // 下一步按钮点击事件 const handleNextClick = () => { // 你可以在这里加自己的表单校验逻辑,校验通过再跳转 // if (!formValid()) return goNextRoute() } return ( <div> {/* 页面内容 */} <button onClick={handleNextClick}>下一步</button> </div> ) }
额外说明
- 如果不需要循环跳转(到最后一个tab后不跳回第一个),可以将计算nextIndex的逻辑修改为
const nextIndex = Math.min(currentIndex + 1, tabPathList.length -1) - 如果需要支持禁止某些tab的跳转,可以在tab的配置项中新增disabled字段,计算nextIndex时跳过disabled为true的项即可
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

