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

如何在api.js中修改App.js的State?401时清除相关状态

解决axios拦截器401时清除App.js状态的问题

首先要修正你代码里的一个关键错误:你用了axios.interceptors.request.use(请求拦截器),但401是响应状态码,应该改用响应拦截器axios.interceptors.response.use,否则无法捕获到响应里的401状态。

下面是几种可行的解决方案:

方法1:给axios实例传入登出回调函数

通过在App.js中定义清除状态的函数,传递给api.js的axios实例,让拦截器可以直接调用这个函数。

修改api.js

/* api.js */
import axios from "axios";

const api = axios.create();

// 存储登出回调的变量
let logoutCallback = null;

// 暴露设置回调的方法
export const setLogoutCallback = (callback) => {
  logoutCallback = callback;
};

// 改用响应拦截器
api.interceptors.response.use(
  (response) => response,
  (error) => {
    // 加?.避免error.response为undefined的情况
    if (error.response?.status === 401) {
      logoutCallback?.(); // 调用清除状态的回调
      console.log("unauthenticated");
    }
    return Promise.reject(error);
  }
);

export default api;

修改App.js

/* App.js */
import { useState, useEffect } from "react";
import api, { setLogoutCallback } from "./api";

function App() {
  const [user, setUser] = useState(null);
  const [shifts, setShifts] = useState([]);
  const [jobs, setJobs] = useState([]);

  // 定义清除所有状态的登出函数
  const handleLogout = () => {
    setUser(null);
    setShifts([]);
    setJobs([]);
    // 可选:清除localStorage/sessionStorage里的token等认证信息
  };

  useEffect(() => {
    // 将登出函数传给api.js
    setLogoutCallback(handleLogout);
    // 组件卸载时清空回调,避免内存泄漏
    return () => setLogoutCallback(null);
  }, [handleLogout]);

  // 其他业务逻辑...
  return <div>你的组件内容</div>;
}

export default App;

方法2:使用React Context全局管理状态

如果项目中需要共享的状态较多,推荐用Context统一管理用户状态和登出逻辑,这样后续其他组件也能方便调用登出方法。

创建AuthContext.js

/* AuthContext.js */
import { createContext, useContext, useState } from "react";

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [shifts, setShifts] = useState([]);
  const [jobs, setJobs] = useState([]);

  const logout = () => {
    setUser(null);
    setShifts([]);
    setJobs([]);
    // 可选:清除认证token
  };

  return (
    <AuthContext.Provider value={{ user, shifts, jobs, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

// 自定义Hook,简化Context调用
export const useAuth = () => useContext(AuthContext);

修改api.js(复用方法1的回调逻辑)

/* api.js */
import axios from "axios";

const api = axios.create();
let logoutCallback = null;

export const setLogoutCallback = (callback) => {
  logoutCallback = callback;
};

api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      logoutCallback?.();
      console.log("unauthenticated");
    }
    return Promise.reject(error);
  }
);

export default api;

修改App.js和入口文件

/* App.js */
import { useEffect } from "react";
import { useAuth } from "./AuthContext";
import api, { setLogoutCallback } from "./api";

function App() {
  const { logout } = useAuth();

  useEffect(() => {
    setLogoutCallback(logout);
    return () => setLogoutCallback(null);
  }, [logout]);

  return <div>你的组件内容</div>;
}

export default App;

在入口文件index.js中用AuthProvider包裹App:

/* index.js */
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { AuthProvider } from "./AuthContext";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <AuthProvider>
    <App />
  </AuthProvider>
);

方法3:使用自定义事件(适合简单场景)

在api.js中触发自定义事件,App.js监听该事件并执行清除状态操作。

修改api.js

/* api.js */
import axios from "axios";

const api = axios.create();

api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      // 触发自定义登出事件
      window.dispatchEvent(new CustomEvent("userLogout"));
      console.log("unauthenticated");
    }
    return Promise.reject(error);
  }
);

export default api;

修改App.js

/* App.js */
import { useState, useEffect } from "react";
import api from "./api";

function App() {
  const [user, setUser] = useState(null);
  const [shifts, setShifts] = useState([]);
  const [jobs, setJobs] = useState([]);

  const handleLogout = () => {
    setUser(null);
    setShifts([]);
    setJobs([]);
  };

  useEffect(() => {
    // 监听自定义事件
    window.addEventListener("userLogout", handleLogout);
    // 组件卸载时移除监听
    return () => window.removeEventListener("userLogout", handleLogout);
  }, []);

  return <div>你的组件内容</div>;
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:32:46