You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router v6 如何在axios拦截器中使用navigate实现页面重定向

根因分析

React Hook 存在严格的调用限制,useNavigate 仅可在React函数组件、自定义Hook的顶层作用域内调用。你当前将useNavigate写在普通JS模块的axios拦截器逻辑中,不在React组件的执行上下文内,因此Hook调用不生效,跳转无法执行。

解决方案

方案1:根组件内初始化拦截器(兼容所有React Router v6版本)

该方案通过在根组件中获取合法的navigate实例,传入拦截器中使用:

  1. 改造axios封装模块,暴露拦截器初始化方法:
// src/utils/api.js
import axios from "axios";

export const api = axios.create({
  baseURL: "http://127.0.0.1:8000/",
  headers: {
    "Content-Type": "application/json",
  },
});

// 接收外部传入的navigate实例注册响应拦截器
export const setupResponseInterceptors = (navigate) => {
  api.interceptors.response.use(
    (response) => response,
    (error) => {
      if (axios.isAxiosError(error) && error.response?.status === 401) {
        // 跳转登录页,replace配置可避免用户点后退回到未授权页
        navigate("/login", { replace: true });
        // 可选:清除本地存储的无效身份凭证
        localStorage.removeItem("user_token");
      }
      return Promise.reject(error);
    }
  );
};
  1. 在应用根组件(如App.jsx)中调用初始化方法:
// src/App.jsx
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { setupResponseInterceptors } from "./utils/api";
import { Outlet } from "react-router-dom";

function App() {
  const navigate = useNavigate();

  useEffect(() => {
    // 应用初始化时仅注册一次拦截器
    setupResponseInterceptors(navigate);
  }, [navigate]);

  return <Outlet />; // 替换为你的应用实际布局/路由出口逻辑
}

export default App;

方案2:直接调用Router实例跳转(适用于React Router v6.4+ 数据路由场景)

如果你使用createBrowserRouter定义路由,可直接导出Router实例,在拦截器中调用其内置的navigate方法,不需要依赖Hook:

  1. 导出路由实例:
// src/router/index.js
import { createBrowserRouter } from "react-router-dom";
import Login from "../pages/Login";
import Home from "../pages/Home";

export const router = createBrowserRouter([
  { path: "/login", element: <Login /> },
  { path: "/", element: <Home /> },
  // 其余路由配置
]);
  1. 拦截器中直接使用Router实例跳转:
// src/utils/api.js
import axios from "axios";
import { router } from "../router";

export const api = axios.create({
  baseURL: "http://127.0.0.1:8000/",
  headers: {
    "Content-Type": "application/json",
  },
});

api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (axios.isAxiosError(error) && error.response?.status === 401) {
      router.navigate("/login", { replace: true });
      localStorage.removeItem("user_token");
    }
    return Promise.reject(error);
  }
);

内容的提问来源于stack exchange,提问作者januw a

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:36:02