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

使用TRPC useQuery遇未处理运行时错误:钩子渲染数量不一致

解决“Rendered more hooks than during the previous render”错误

错误原因

你遇到的这个错误是违反了React Hooks核心规则导致的:所有Hooks必须在组件的顶层作用域调用,不能放在条件判断、循环或嵌套函数里。

初始渲染时路由参数id还未加载完成,你的代码会提前返回<LoadingSpinner />,此时根本没调用useQuery;当id加载完成后,组件会继续执行到useQuery的调用,导致两次渲染的Hooks数量不一致,直接触发报错——哪怕你设置了enabled: false也没用,因为问题出在Hook是否被调用,而非它是否执行查询。

最简单的解决方法

把useQuery移到组件顶层,通过enabled选项控制查询是否执行,同时保留对id的校验逻辑:

import type { NextPage } from "next";

import Image from "next/image";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { api } from "@/utils/api";
import { LoadingSpinner } from "@/components/loading";

const EvaluationPage: NextPage = () => {
  const { data: session } = useSession();
  const router = useRouter();
  const { id } = router.query;

  // 将useQuery移至组件顶层,确保每次渲染都调用该Hook
  const { data } = api.image.getEvaluation.useQuery(
    {
      id: id as string, // 添加类型断言,后续会校验id合法性
    },
    {
      // 仅当id为有效非数组字符串时,启用查询
      enabled: !!id && !Array.isArray(id),
    }
  );

  // 原提前返回逻辑移至Hook调用之后
  if (!id || Array.isArray(id)) {
    return <LoadingSpinner />;
  }

  return (
    <>
      <main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-br from-blue-400 to-indigo-800">
        {session ? (
          <div className="container flex flex-col items-center justify-center gap-12 px-4 py-12 ">
            <h1 className="font-base text-3xl tracking-tight text-gray-100 sm:text-3xl">
              Image evaluation
            </h1>

            <>{data && <p className="text-white">{data.response}</p>}</>
          </div>
        ) : (
          <div className="flex flex-col items-center justify-center gap-4 py-4">
            <h3 className="text-center text-2xl text-gray-100">
              Please sign in to continue.
            </h3>
          </div>
        )}
      </main>
    </>
  );
};

关键修改点说明

  1. Hook移至顶层:无论id是否存在,每次渲染都会调用useQuery,保证Hooks调用数量始终一致,从根源解决报错。
  2. 动态控制查询启用:通过enabled: !!id && !Array.isArray(id)实现仅当id有效时才触发查询,和你原本想通过enabled: false实现的效果一致。
  3. 保留加载状态:原提前返回逻辑调整位置后,不影响用户看到的加载效果,只是调整了执行顺序以符合Hooks规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:05:26