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

React中如何在非组件函数内处理API 401并实现页面重定向?

解决方案

方案1:使用React Router全局导航实例

React Router v6+ 可以在路由初始化时获取navigate函数,将其全局导出供非组件文件调用:

  1. 在路由配置文件(如router.js)中:
import { createBrowserRouter, RouterProvider, useNavigation } from 'react-router-dom';

// 声明全局navigate变量
let navigate;
const router = createBrowserRouter([
  // 你的路由配置项
]);

// 自定义Router组件,获取并赋值navigate
function AppRouter() {
  const navigation = useNavigation();
  navigate = navigation.navigate;
  return <RouterProvider router={router} />;
}

export { navigate, AppRouter };
  1. 在apiCalls.js中导入使用:
import { navigate } from './router';

export async function getData() {
  try {
    const response = await fetch(url);
    const res = await response.json(); // 注意这里要加await,原代码遗漏了异步处理
    if (res.status.code === 401) {
      // 清除本地存储的令牌(如果有)
      localStorage.removeItem('token');
      navigate('/login');
    }
    return res;
  } catch (err) {
    console.error('请求出错:', err);
  }
}

注:需确保navigate在组件挂载后才会被赋值,若有组件初始化时就调用API,建议加非空判断。

方案2:封装统一请求拦截器

创建基础请求函数,所有API调用基于该函数,统一处理401错误,无需依赖React Router:

// apiCalls.js
async function baseRequest(url, options = {}) {
  const response = await fetch(url, options);
  const res = await response.json();
  
  if (res.status.code === 401) {
    localStorage.removeItem('token');
    // 用原生跳转直接指向登录页
    window.location.href = '/login';
    throw new Error('未授权,请重新登录');
  }
  
  return res;
}

// 基于基础函数封装具体API
export async function getData() {
  return baseRequest(url);
}

export async function postData(data) {
  return baseRequest(url, {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json' }
  });
}

这个方案简单直接,适合不需要React Router路由状态的场景。

方案3:事件总线解耦API与路由

在API层触发自定义事件,根组件监听事件并执行重定向,实现关注点分离:

  1. 在apiCalls.js中触发事件:
export async function getData() {
  const response = await fetch(url);
  const res = await response.json();
  
  if (res.status.code === 401) {
    localStorage.removeItem('token');
    // 触发自定义未授权事件
    window.dispatchEvent(new CustomEvent('unauthorized'));
  }
  
  return res;
}
  1. 在根组件(如App.js)中监听事件:
import { useNavigate, useEffect } from 'react-router-dom';

function App() {
  const navigate = useNavigate();
  
  useEffect(() => {
    function handleUnauthorized() {
      navigate('/login');
    }
    
    window.addEventListener('unauthorized', handleUnauthorized);
    // 组件卸载时移除监听
    return () => window.removeEventListener('unauthorized', handleUnauthorized);
  }, [navigate]);
  
  return (
    // 你的组件内容
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:25:47