使用QueryClientProvider包裹App.ts时触发Next.js组件传值错误
错误原因
你的Home组件是Server Component(因使用async/await调用auth()),你在Server Component中创建了QueryClient类实例,并将其作为props传递给QueryClientProvider。Next.js规定Server Component向Client Component传递props时,仅支持纯对象、基本数据类型等简单值,不允许传递类实例或无原型对象,这就是报错的核心原因。
修复方案
将React Query的Provider逻辑移到独立的Client Component中,避免在Server Component中传递类实例。
步骤1:创建React Query Provider包装组件
在项目中新建一个标记为"use client"的组件,比如app/providers/ReactQueryProvider.tsx:
"use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useState } from "react"; export function ReactQueryProvider({ children }: { children: React.ReactNode }) { // 在Client Component中创建QueryClient实例 const [queryClient] = useState(() => new QueryClient()); return ( <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> ); }
步骤2:修改Home组件
移除Home组件中QueryClient和QueryClientProvider的导入,改用上面创建的包装组件包裹页面内容:
import Image from 'next/image' import { Button } from '@/components/ui/button' import { UserButton, auth } from '@clerk/nextjs' import Link from 'next/link'; import { LogIn } from 'lucide-react'; import FileUpload from '@/components/FileUpload'; import { ReactQueryProvider } from './providers/ReactQueryProvider'; export default async function Home() { const { userId } = await auth(); const isAuth = !!userId; return ( <ReactQueryProvider> <div className='w-screen min-h-screen bg-gradient-to-b from-black via-black to-sky-900'> <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-white'> <div className="flex flex-col items-center text-center"> <div className="flex items-center"> <h1 className='mr-3 text-5xl font-bold-sans md:font-serif bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-400'>Chat With Any PDF</h1> <UserButton afterSignOutUrl='/'/> </div> <div className="flex mt-2"> {isAuth && <Button className='mb-2 bg-gradient-to-r from-black via-black to-sky-900 border-2 border-gray-300 border-r-2 hover:bg-gradient-to-l hover:transition hover:duration-300'>Go to Chats</Button>} </div> <p className='mt-1 md:font-serif bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-400'>Script.Ai is a cutting-edge web application designed to streamline your PDF interactions. Simply upload your documents and effortlessly extract answers to your questions, harnessing the power of advanced AI technology for precision and efficiency.</p> <div className='w-full mt-4'> {isAuth ? (<FileUpload/>):<Link href={'/sign-in'} > <Button className='bg-gradient-to-r from-black via-black to-sky-900 text-gray-300 border-2 border-gray-300 hover:bg-gradient-to-l hover:transition hover:duration-300 hover:ease-in-out'>Login to get Started <LogIn className='w-4 h-4 ml-2 '/> </Button> </Link> } </div> </div> </div> </div> </ReactQueryProvider> ) }
原理说明
通过将QueryClient的创建和QueryClientProvider的包裹逻辑放到标记了"use client"的组件中,所有React Query相关的实例化和上下文提供都在客户端完成,彻底避免了Server Component向Client Component传递类实例的问题,同时保留了Home组件作为Server Component获取用户信息的能力。
内容的提问来源于stack exchange,提问作者Tirth Joshi
相关产品推荐
相关产品推荐

