React Hook调用无效问题排查:复用请求Header报错求助
问题排查:React Hook调用错误及复用请求头方案
我已经查过其他类似问题并尝试了相应解决方案,但还是搞不懂为什么我的代码无法正常运行。我想通过工具文件复用请求头(遵循DRY原则),在不同API中使用,需要帮忙排查问题原因。
报错信息
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1
相关代码
headers.tsx
import { useSession } from "next-auth/react"; const useHeaders = () => { const { data: Session } = useSession(); let token = "" if (Session){ // @ts-ignore token = Session.accessToken } const authToken = `Bearer ${token}`; return { headers: { Authorization: authToken, }, }; }; export default useHeaders
users.tsx
import axios from "axios"; import useHeaders from "../../utils/headers" export function fetchUsers() { const headers = useHeaders(); const url = `${process.env.NEXT_PUBLIC_VEXO_URL}/v1/ke/user/list` return axios .get(url, headers) .then((res) => res) .catch((err) => err); }
问题原因及修复方案
问题根源
useHeaders是自定义React Hook,而fetchUsers是普通工具函数。React的Hook规则明确要求:Hook只能在React函数组件的顶层,或者其他自定义Hook的顶层调用,不能在普通函数、循环、条件判断里调用,这就是你报错的直接原因。
修复方案1:将fetchUsers改为自定义Hook
把fetchUsers改成Hook,这样就能合法调用useHeaders:
import axios from "axios"; import useHeaders from "../../utils/headers" export function useFetchUsers() { const headers = useHeaders(); const url = `${process.env.NEXT_PUBLIC_VEXO_URL}/v1/ke/user/list` const fetchUsers = () => { return axios .get(url, headers) .then((res) => res) .catch((err) => err); }; return fetchUsers; }
在React组件中使用:
import { useFetchUsers } from './users'; import { useEffect } from 'react'; function UserList() { const fetchUsers = useFetchUsers(); useEffect(() => { fetchUsers().then(res => { // 处理返回的数据 }); }, [fetchUsers]); // 其他组件逻辑 }
修复方案2:将headers工具改为普通函数,传入session参数
如果不想把API调用改为Hook,可以把useHeaders改成普通函数,从外部传入session:
修改headers.tsx:
export function getAuthHeaders(session?: any) { let token = ""; if (session) { // @ts-ignore token = session.accessToken; } const authToken = `Bearer ${token}`; return { headers: { Authorization: authToken, }, }; }
修改users.tsx:
import axios from "axios"; import { getAuthHeaders } from "../../utils/headers" export function fetchUsers(session?: any) { const headers = getAuthHeaders(session); const url = `${process.env.NEXT_PUBLIC_VEXO_URL}/v1/ke/user/list` return axios .get(url, headers) .then((res) => res) .catch((err) => err); }
在React组件中使用:
import { useSession } from "next-auth/react"; import { fetchUsers } from './users'; import { useEffect } from 'react'; function UserList() { const { data: session } = useSession(); useEffect(() => { fetchUsers(session).then(res => { // 处理返回的数据 }); }, [session]); // 其他组件逻辑 }
内容的提问来源于stack exchange,提问作者siderra
相关产品推荐
相关产品推荐

