react-router-dom v6.21.1:非组件函数内页面跳转方案求助
解决react-router-dom v6非组件函数内页面跳转问题
问题原因
useNavigate是React Hook,必须遵循Hook规则:只能在React函数组件或自定义Hook(命名以use开头)中调用,普通函数parseToken里调用会触发规则报错。redirect是路由专属动作函数,仅在路由加载器(loader)或动作(action)上下文里生效,普通函数调用无法触发页面跳转。
解决方案
方案1:将parseToken改为自定义Hook
把函数命名改为符合自定义Hook规则的useParseToken,即可合法使用useNavigate:
import { useNavigate } from "react-router-dom"; import { ILogin } from "../Pages/Login/ILogin"; import { decode } from "./encodeDecode"; export const useParseToken = () => { const nav = useNavigate(); const parse = () => { try { const token: ILogin = decode(localStorage.getItem("token")); return token; } catch (error) { console.log(error); alert("Invalid Credentials"); localStorage.clear(); nav("/login"); return null; } }; return parse; };
组件内使用示例:
import { useParseToken } from './path-to-parseToken'; function SomeComponent() { const parseToken = useParseToken(); const token = parseToken(); // 组件业务逻辑 }
方案2:传递navigate函数作为参数
从调用parseToken的组件中传入useNavigate返回的跳转函数,避免在普通函数中直接使用Hook:
import { ILogin } from "../Pages/Login/ILogin"; import { decode } from "./encodeDecode"; export const parseToken = (navigate: any) => { try { const token: ILogin = decode(localStorage.getItem("token")); return token; } catch (error) { console.log(error); alert("Invalid Credentials"); localStorage.clear(); navigate("/login"); } };
组件内调用示例:
import { useNavigate } from 'react-router-dom'; import { parseToken } from './path-to-parseToken'; function SomeComponent() { const navigate = useNavigate(); const token = parseToken(navigate); // 组件业务逻辑 }
方案3:使用全局路由实例
如果项目用createBrowserRouter创建路由,可将路由实例全局导出,直接调用router.navigate实现跳转:
首先在路由配置文件中导出实例:
import { createBrowserRouter } from "react-router-dom"; export const router = createBrowserRouter([ // 你的路由配置项 ]);
然后在parseToken中使用:
import { router } from './path-to-router-config'; import { ILogin } from "../Pages/Login/ILogin"; import { decode } from "./encodeDecode"; export const parseToken = () => { try { const token: ILogin = decode(localStorage.getItem("token")); return token; } catch (error) { console.log(error); alert("Invalid Credentials"); localStorage.clear(); router.navigate("/login"); } };
注意事项
- 方案1、2遵循React Hook规则,是推荐的常规做法;方案3适合非组件/非Hook环境下的跳转需求,但需注意全局路由实例的维护。
- 触发跳转后建议提前返回(如
return null),避免函数后续不必要的逻辑执行。
内容的提问来源于stack exchange,提问作者santhosh
相关产品推荐
相关产品推荐

