提问人:Văn Thuận Nguyễn 提问时间:11/16/2023 最后编辑:Drew ReeseVăn Thuận Nguyễn 更新时间:11/16/2023 访问量:40
无效的挂钩调用。只有在将 useNavigate 和 useEffect 与 axios 拦截器一起使用时,才能在函数组件的主体内部调用钩子
Invalid hook call. Hooks can only be called inside of the body of a function component when using useNavigate and useEffect with axios interceptors
问:
我正在研究 React 并尝试包含用于私有 API 调用的持有者令牌。我写了一个私有 axios 来拦截请求和响应。然后我在 API.js 中调用它以从服务器获取数据。但是,我收到此错误:
错误:挂钩调用无效。钩子只能在身体内部调用 函数组件。以下情况之一可能会发生这种情况 原因:
你可能有不匹配的 React 和渲染器(例如 React DOM)的版本
你可能违反了钩子的规则
你可能在同一个应用中有多个 React 副本
它来自和进来useNavigate
useEffect
privateAxios.js
私人Axios.js
import { axiosPrivate } from "./axios";
import { useEffect } from "react";
// import useRefreshToken from "./useRefreshToken";
import { useNavigate } from "react-router-dom";
const usePrivateAxios = () => {
const navigate = useNavigate();
useEffect(() => {
const requestInterceptor = axiosPrivate.interceptors.request.use(
(config) => {
const accessToken = localStorage.getItem("accessToken");
if (!accessToken) {
navigate("/admin/login");
} else {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => Promise.reject(error),
);
const responseInterceptor = axiosPrivate.interceptors.response.use(
(response) => {
return response;
},
(error) => {
return Promise.reject(error);
},
);
return () => {
axiosPrivate.interceptors.request.eject(requestInterceptor);
axiosPrivate.interceptors.response.eject(responseInterceptor);
};
}, [navigate]);
return axiosPrivate;
};
export default usePrivateAxios;
文档API.js
import privateAxios from "../usePrivateAxios";
export const getAllDocuments = (config) => {
return privateAxios()
.get("/documents", config)
.then((response) => response.data)
.catch((error) => {
throw error;
});
};
我想使用重定向到登录,所以我使用这种方法。useNavigate
答:
1赞
Drew Reese
11/16/2023
#1
usePrivateAxios
是一个 React 钩子,所以它必须遵循钩子的规则。在您的代码中,您已将其导入为函数,并在该函数中调用它,该函数既不是 React 函数组件,也不是自定义 React 钩子。privateAxios
由于您只是将请求/响应拦截器注入到 axios 对象中,因此无需使用返回值 from 来发出 GET 请求。 只需在应用中调用一次即可添加拦截器,该函数可以使用 Axios 对象。axiosPrivate
usePrivateAxios
usePrivateAxios
getAllDocuments
privateAxios
例:
App.jsx(应用程序.jsx)
...
import usePrivateAxios from "../usePrivateAxios";
...
const App = () => {
// Setup global axios request/response interceptors
usePrivateAxios();
...
return (
...
);
}
<BrowserRouter>
<App />
</BrowserRouter>
文档API.js
import { axiosPrivate } from "./axios";
export const getAllDocuments = (config) => {
return axiosPrivate()
.get("/documents", config)
.then((response) => response.data)
.catch((error) => {
throw error;
});
};
评论