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

Preact+React-Query中调用useAuth0获取Auth0 Access Token报错求助

问题分析与解决方案

错误原因

你遇到的Cannot read properties of null (reading 'context')错误,核心是违反了React/Preact的Hook调用规则:Hook只能在组件或自定义Hook的顶层调用,不能在普通异步函数(比如你的apiGet)内部调用useAuth0。这种情况下,Hook无法正确关联到组件上下文,导致上下文查找失败。

解决方案(满足Token逻辑封装需求)

方案一:抽离Token获取Hook,传递给API函数

先把Token获取逻辑封装成自定义Hook,再将Token获取方法传递给API函数:

  1. 封装Token获取Hook
export const useAuthToken = () => {
  const { getAccessTokenSilently } = useAuth0();
  // 返回一个异步函数,用于获取Token
  return async () => getAccessTokenSilently();
};
  1. 修改API函数,接收Token获取方法
export const apiGet = async (getToken) => {
  const token = await getToken();
  const response = await axios.get("[API URL]", {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });
  return response.data;
};
  1. 在数据Hook中使用
export const useGetData = () => {
  const getToken = useAuthToken();
  return useQuery(["test"], () => apiGet(getToken));
};

方案二:用Axios拦截器全局处理Token注入(更优雅)

通过自定义Hook创建带拦截器的Axios实例,自动在请求头添加Token,无需每个API调用手动处理:

  1. 创建带Auth拦截的Axios实例Hook
import axios from 'axios';
import { useAuth0 } from '@auth0/auth0-react';

export const useApiClient = () => {
  const { getAccessTokenSilently } = useAuth0();
  const apiClient = axios.create({
    baseURL: "[API BASE URL]" // 替换为你的API基础地址
  });

  // 请求拦截器:自动注入Token
  apiClient.interceptors.request.use(async (config) => {
    const token = await getAccessTokenSilently();
    config.headers.Authorization = `Bearer ${token}`;
    return config;
  });

  return apiClient;
};
  1. 简化API调用
// 可以直接在数据Hook中使用apiClient,无需单独的apiGet函数
export const useGetData = () => {
  const apiClient = useApiClient();
  return useQuery(["test"], async () => {
    const response = await apiClient.get("[API ENDPOINT]"); // 替换为具体接口路径
    return response.data;
  });
};

如果需要复用API逻辑,也可以封装成方法:

// 封装API方法
export const createApi = (apiClient) => ({
  getTestData: async () => {
    const res = await apiClient.get("[API ENDPOINT]");
    return res.data;
  },
  // 其他接口方法...
  postData: async (payload) => {
    const res = await apiClient.post("[POST ENDPOINT]", payload);
    return res.data;
  }
});

// 在数据Hook中使用
export const useGetData = () => {
  const apiClient = useApiClient();
  const { getTestData } = createApi(apiClient);
  return useQuery(["test"], getTestData);
};

核心思路

所有需要调用Hook的逻辑必须放在组件或自定义Hook的顶层,然后将获取到的能力(Token获取方法、配置好的请求实例)传递给普通的API函数,既实现了Token逻辑的封装,又严格遵守Hook规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:25:18