React Query SSR组件:兼容带参/无参函数Props的类型配置
改造RQBoundary组件以支持带参/无参预取函数
问题背景
当前实现的RQBoundary组件用于React Query SSR数据预取,但fn属性仅支持无参的() => Promise<T>类型。当需要传递带参数的fetch函数时,会触发类型错误:
Type '(id: string) => Promise<ResponsePost>' is not assignable to type '() => Promise<ResponsePost>'. Target signature provides too few arguments. Expected 1 or more, but got 0.
需求是不新建类似RQParamsBoundary的独立组件,让同一个RQBoundary同时兼容无参和带参的预取函数。
改造方案
通过泛型条件类型和可选参数实现兼容,改造后的组件代码如下:
import { dehydrate, HydrationBoundary } from '@tanstack/react-query'; import getQueryClient from '@/lib/react-query/getQueryClient'; export async function RQBoundary<T, Params = void>({ children, queryKey, fn, params, }: { children: React.ReactNode; queryKey: string[]; fn: Params extends void ? () => Promise<T> : (params: Params) => Promise<T>; params?: Params; }) { const queryClient = getQueryClient(); await queryClient.prefetchQuery({ queryKey, queryFn: () => { if (params !== undefined) { return fn(params as Params); } return (fn as () => Promise<T>)(); }, }); const dehydratedState = dehydrate(queryClient); return ( <HydrationBoundary state={dehydratedState}>{children}</HydrationBoundary> ); }
改造关键点
- 新增
Params泛型参数,默认值设为void,对应原无参场景 - 利用条件类型自动适配
fn的类型:当Params为void时,fn是无参函数;否则是接收Params类型参数的函数 - 添加可选的
params属性,用于传递带参函数所需的参数 - 在
queryFn内部根据params是否存在,调用对应形式的预取函数
使用示例
无参场景(保持原有用法)
export default function Page() { return ( <RQBoundary queryKey={['posts']} fn={getPosts}> <PostTable /> </RQBoundary> ); }
带参场景
export default function PostDetailPage({ params }: { params: { id: string } }) { return ( <RQBoundary<ResponsePost, string> queryKey={['post', params.id]} fn={(postId) => getPostById(postId)} params={params.id} > <PostContent /> </RQBoundary> ); }
这样改造后,无需新增组件即可同时支持两种场景,且TypeScript类型检查依然有效,不会出现类型不兼容的错误。
内容的提问来源于stack exchange,提问作者pvp11
相关产品推荐
相关产品推荐

