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

tRPC v10报错:Query data cannot be undefined 求助

解决tRPC v10中"Query data cannot be undefined"报错问题

错误原因分析

你遇到的Query data cannot be undefined报错,核心原因是开启SSR后,客户端React Query在hydration阶段无法获取到服务器端预取的数据,或者React Query的严格模式默认不允许查询数据为undefined。结合你的代码,主要问题集中在SSR配置和数据预取环节。

具体解决方案

1. 调整Query Client默认配置

在utils/trpc.ts中启用并修改queryClientConfig,关闭严格模式或允许数据为undefined:

export const trpc = createTRPCNext<AppRouter, SSRContext>({
    config({ ctx }) {
        return {
            transformer: superjson,
            links: [
                httpBatchLink({
                    url: `${getBaseUrl()}/api/trpc`,
                }),
            ],
            // 启用并修改查询客户端配置
            queryClientConfig: {
                defaultOptions: {
                    queries: {
                        staleTime: 60,
                        // 关闭严格模式,允许数据为undefined
                        strict: false,
                        // 可选:关闭自动重试,减少调试干扰
                        retry: false,
                    },
                },
            },
            headers() {
                // 原headers逻辑保持不变
                if (ctx?.req) {
                    const { connection: _connection, ...headers } = ctx.req.headers;
                    return {
                        ...headers,
                        "x-ssr": "1",
                    };
                }
                return {};
            },
        };
    },
    ssr: true,
});

2. 为页面添加服务器端数据预取

因为你开启了ssr: true,必须在服务器端预取页面所需的所有tRPC查询数据,确保客户端hydration时能拿到数据。修改pages/test.tsx:

import React from "react";
import { NextPage, GetServerSideProps } from "next";
import { trpc } from "@/utils/trpc";

const TestPage: NextPage = () => {
    const helloNoArgs = trpc.authy.hello.useQuery();
    const helloWithArgs = trpc.authy.hello.useQuery({ text: "client" });
    const greeting = trpc.greeting.useQuery();

    return (
        <div>
            <h1>Hello World Example</h1>
            <ul>
                <li>
                    helloNoArgs ({helloNoArgs.status}):{" "}
                    <pre>{JSON.stringify(helloNoArgs.data, null, 2)}</pre>
                </li>
                <li>
                    helloWithArgs ({helloWithArgs.status}):{" "}
                    <pre>{JSON.stringify(helloWithArgs.data, null, 2)}</pre>
                </li>
                <li>
                    greeting ({greeting.status}):{" "}
                    <pre>{JSON.stringify(greeting.data, null, 2)}</pre>
                </li>
            </ul>
        </div>
    );
};

// 添加服务器端预取逻辑
export const getServerSideProps: GetServerSideProps = async (ctx) => {
    const trpcCaller = trpc.createCaller(ctx);
    // 预取页面所有用到的查询
    await Promise.all([
        trpcCaller.authy.hello(),
        trpcCaller.authy.hello({ text: "client" }),
        trpcCaller.greeting(),
    ]);
    return { props: {} };
};

export default TestPage;

3. 简化Input Schema(可选)

server/router/authy.ts中的input schema存在冗余的.nullish().optional(),可以简化为:

.input(z.object({ text: z.string().nullish() }).optional())

或者更简洁的写法:

.input(z.object({ text: z.string() }).nullish())

4. 验证API路由配置

确保pages/api/trpc/[trpc].ts存在且配置正确,这是tRPC客户端与服务器通信的核心入口:

import { createNextApiHandler } from "@trpc/server/adapters/next";
import { appRouter } from "@/server/router/_app";
import { createContext } from "@/server/trpc";

export default createNextApiHandler({
    router: appRouter,
    createContext,
});

生效原理

  • 关闭React Query的strict模式,会解除"数据不能为undefined"的限制,避免hydration阶段的报错;
  • 服务器端预取数据后,tRPC会自动将数据同步到客户端的Query Client,确保客户端渲染时能直接拿到数据;
  • 简化schema避免不必要的类型解析歧义,减少潜在的序列化问题;
  • 正确的API路由是tRPC客户端与服务器建立通信的基础,缺失或配置错误会导致所有查询失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:45:33