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

如何在调用useQuery()前等待NextAuth会话加载完成?

解决NextAuth useSession返回undefined导致React Query获取数据失败的问题

核心问题

useSession()在会话验证完成前会返回undefined,此时直接执行useQuery会传入无效的userID,导致接口请求失败。要解决这个问题,关键是让useQuery仅在会话成功获取到有效userID后再触发。

方案一:使用useQuery的enabled选项(最直接)

React Query的useQuery提供了enabled配置项,只有当该值为true时才会执行查询。我们可以将其设置为是否存在有效userID的判断结果,同时把userID加入查询键,确保用户切换时自动重新查询。

const AirdropsPage = () => {
  const { data: session } = useSession();

  const { isLoading, isError, data } = useQuery(
    ["airdropsData", session?.user?.id], // 把userID加入查询键,用户切换时自动重查
    () => fetch(`/api/airdrops?id=${session.user.id}`).then(res => res.json()),
    {
      enabled: !!session?.user?.id // 仅当userID存在时启用查询
    }
  );

  return (
    <>
      {isLoading ? (
        <Loader />
      ) : data ? (
        <Table data={data.airdrops} columns={columns} />
      ) : isError ? (
        <div>加载失败,请重试</div>
      ) : (
        <div>请先登录查看内容</div>
      )}
    </>
  );
};

方案二:结合useSession的状态判断(更清晰)

NextAuth的useSession会返回status字段(值为loading/authenticated/unauthenticated),我们可以先根据状态处理会话加载中、未登录的情况,确保进入查询逻辑时session一定是有效的。

const AirdropsPage = () => {
  const { data: session, status } = useSession();

  // 会话加载中时显示全局加载器
  if (status === "loading") {
    return <Loader />;
  }

  // 未登录时提示登录
  if (status === "unauthenticated") {
    return <div>请登录后查看空投数据</div>;
  }

  // 此处session已确保为authenticated状态,可安全使用userID
  const { isLoading, isError, data } = useQuery(
    ["airdropsData", session.user.id],
    () => fetch(`/api/airdrops?id=${session.user.id}`).then(res => res.json())
  );

  return (
    <>
      {isLoading ? (
        <Loader />
      ) : data ? (
        <Table data={data.airdrops} columns={columns} />
      ) : isError ? (
        <div>加载失败,请重试</div>
      ) : null}
    </>
  );
};

方案三:拆分组件(类型更安全)

将查询逻辑抽成独立子组件,仅当userID存在时才渲染该组件,子组件内无需处理undefined的情况,类型更严谨。

// 子组件:仅接收已确认的userID
const AirdropsTable = ({ userId }: { userId: string }) => {
  const { isLoading, isError, data } = useQuery(
    ["airdropsData", userId],
    () => fetch(`/api/airdrops?id=${userId}`).then(res => res.json())
  );

  return (
    <>
      {isLoading ? (
        <Loader />
      ) : data ? (
        <Table data={data.airdrops} columns={columns} />
      ) : isError ? (
        <div>加载失败,请重试</div>
      ) : null}
    </>
  );
};

// 父组件:控制会话状态
const AirdropsPage = () => {
  const { data: session, status } = useSession();

  if (status === "loading") {
    return <Loader />;
  }

  if (status === "unauthenticated") {
    return <div>请登录后查看内容</div>;
  }

  return <AirdropsTable userId={session.user.id} />;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:26:17