서스펜스
비공식 베타 번역
이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
정보
- React 최신 버전을 사용 중인지 확인하세요
- Next.js에서 tRPC의 자동 SSR과 함께 서스펜스를 사용할 경우, 쿼리 실패 시
<ErrorBoundary />가 있더라도 서버에서 전체 페이지가 충돌합니다
사용법
팁
useSuspenseQuery와 useSuspenseInfiniteQuery는 모두 [data, query]-튜플을 반환하여 데이터에 직접 접근하고 변수명을 설명적인 이름으로 변경하기 쉽게 합니다
useSuspenseQuery()
tsximport { trpc } from '../utils/trpc';function PostView() {const [post, postQuery] = trpc.post.byId.useSuspenseQuery({ id: '1' });return <>{/* ... */}</>;}
tsximport { trpc } from '../utils/trpc';function PostView() {const [post, postQuery] = trpc.post.byId.useSuspenseQuery({ id: '1' });return <>{/* ... */}</>;}
useSuspenseInfiniteQuery()
tsximport { trpc } from '../utils/trpc';import type { PostPage }from '../server'; function PostView() { const [{ pages }, allPostsQuery] = trpc.post.all.useSuspenseInfiniteQuery({},{getNextPageParam(lastPage: PostPage) {return lastPage.nextCursor; },initialCursor: '',},);const { isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } =allPostsQuery;return <>{/* ... */}</>;}
tsximport { trpc } from '../utils/trpc';import type { PostPage }from '../server'; function PostView() { const [{ pages }, allPostsQuery] = trpc.post.all.useSuspenseInfiniteQuery({},{getNextPageParam(lastPage: PostPage) {return lastPage.nextCursor; },initialCursor: '',},);const { isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } =allPostsQuery;return <>{/* ... */}</>;}
useSuspenseQueries()
useQueries()의 서스펜스 버전입니다.
tsximport { trpc } from '../utils/trpc';const Component = (props: { postIds: string[] }) => {const [posts, postQueries] = trpc.useSuspenseQue ries((t) =>props.postIds.map((id) => t.post.byId({ id })),);return <>{/* [...] */}</>;};
tsximport { trpc } from '../utils/trpc';const Component = (props: { postIds: string[] }) => {const [posts, postQueries] = trpc.useSuspenseQue ries((t) =>props.postIds.map((id) => t.post.byId({ id })),);return <>{/* [...] */}</>;};
프리페칭
서스펜스 컴포넌트 렌더링 전에 쿼리 데이터를 프리페칭하면 서스펜스 쿼리 성능을 개선할 수 있습니다 (이를 "render-as-you-fetch"라고도 함).
참고
- 프리페칭과 render-as-you-fetch 모델은 사용 중인 프레임워크와 라우터에 크게 의존합니다. 이러한 패턴 구현 방법을 이해하려면 프레임워크 라우터 문서와 @tanstack/react-query 문서를 함께 참고하시기 바랍니다.
- Next.js를 사용 중이라면 서버 사이드 프리페칭 구현을 위해 Server-Side Helpers 문서를 확인해 주세요.
라우트 수준 프리페칭
tsximport {createTRPCQuery Utils } from '@trpc/react-query';import {createTRP CClient, httpBatchLink } from '@trpc/client';import { QueryClient } from '@tanstack/react-query';import type{ AppRouter } from './server'; const queryClient = new QueryClient();const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:3000' })] });const utils = createTRPCQueryUtils({ queryClient, client: trpcClient });// tanstack router/ react router loader const loader = async (params: { id: string }) =>utils.post.byId.ensureData({ id: params.id });
tsximport {createTRPCQuery Utils } from '@trpc/react-query';import {createTRP CClient, httpBatchLink } from '@trpc/client';import { QueryClient } from '@tanstack/react-query';import type{ AppRouter } from './server'; const queryClient = new QueryClient();const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:3000' })] });const utils = createTRPCQueryUtils({ queryClient, client: trpcClient });// tanstack router/ react router loader const loader = async (params: { id: string }) =>utils.post.byId.ensureData({ id: params.id });
컴포넌트 수준 프리페칭 (usePrefetchQuery 사용)
tsximport React, { Suspense } from 'react';import { trpc } from '../utils/trpc';function PostView(props: { postId: string }) { return <></>;}function PostViewPage(props: { postId: string }) {trpc.post.byId.usePrefetchQuery({ id: props.postId });return (<Suspense><PostView postId={props.postId} /></Suspense>);}
tsximport React, { Suspense } from 'react';import { trpc } from '../utils/trpc';function PostView(props: { postId: string }) { return <></>;}function PostViewPage(props: { postId: string }) {trpc.post.byId.usePrefetchQuery({ id: props.postId }); return (<Suspense><PostView postId={props.postId} /></Suspense>);}
컴포넌트 수준 프리페칭 (usePrefetchInfiniteQuery 사용)
tsximport React, { Suspense } from 'react';import { trpc } from '../utils/trpc';import type { PostPage } from '../server';function PostView(props: { postId: string }) {return <></>;}function PostViewPage(props: { postId: string }) { trpc.post.all.usePrefetchInfiniteQuery({},{getNextPageParam(lastPage: PostPage) {return lastPage.nextCursor;},initialCursor: '',},);return (<Suspense><PostView postId={props.postId} /></Suspense>);}
tsximport React, { Suspense } from 'react';import { trpc } from '../utils/trpc';import type { PostPage } from '../server';function PostView(props: { postId: string }) {return <></>;}function PostViewPage(props: { postId: string }) { trpc.post.all.usePrefetchInfiniteQuery({},{getNextPageParam(lastPage: PostPage) {return lastPage.nextCursor;},initialCur sor: '',},);return (<Suspense><PostView postId={props.postId} /></Suspense>);}