
이전에도 언급한 적이 있지만 React Query는 정말 좋은 비동기 처리 라이브러리이다.
하지만 Suspense와의 연동성이 좋지 않아 최근에는 자주 사용하지 않고 있었다.
저번 달에 React Query v5가 출시되었다.
이 버전에는 Suspense와의 연동은 물론이고 Next.js의 Streaming과의 연동성도 매우 좋아졌다.
이번 글에서는 React Query v5의 주요 변경점과 함께 Next.js과는 어떻게 연결 지어야 하는지 다뤄보려고 한다.
One Function One Parameter

React Query에 있는 모든 Hook, Method들은 이제 하나의 Parameter를 갖게된다.
여러 개의 Parameter를 갖던 경우에는 Object 형태로 받을 수 있게 바뀌었다.
이 부분은 codemon을 통해 마이그레이션 가능하다고 가이드되고 있다.
Callback options are deprecated
query에는 onSuccess, onError와 같은 Callback 함수를 옵션으로 제공하였다.
v5에서는 이 부분을 Query의 일관성을 위해 제거시켰다고 한다.
(사실 좀 자주 사용하던 옵션인데 이 옵션이 편하기는 하지만 이 옵션이 유지 보수 측면에서 헷갈리게 만든다는 점은 어느 정도 동의를 하고 있었는데 제거될 것이라고는 생각도 못했다)
Etc..
- TypeScript 4.7+ for 타입 추론
- Error Type: unknown -> Error
- cacheTime -> gcTime (기능은 바뀌지 않음)
With Next.js
Next.js에서는 Streaming이라는 기술을 통해 사용자 경험을 향상시킨다.
이 글을 참고하면 좋을 것 같은데, 간단히 요약하면 Suspense 문법을 사용해 모든 컴포넌트가 로딩되기 이전에 다른 UI와 상호작용할 수 있게 해주는 기술이다.
Streaming 기술을 사용하기 위해 다양한 방법들이 있지만, React Query v5에서 정식으로 지원하는 문법인 useSuspenseQuery를 사용하면 더 쉽게 구현할 수 있다.
예시 코드와 함께 설명하면 좋을 것 같은데
import Loading from '@components/ui/loading';
import { Suspense } from 'react';
import WaitingComponent from './wating-component';
export const runtime = 'edge'; // 'nodejs' (default) | 'edge'
export default function ReactQueryExample() {
return (
<main>
<h1>React Query Test</h1>
<ul>
<Suspense fallback={<div>waiting 100....</div>}>
<WaitingComponent wait={100} />
</Suspense>
<Suspense fallback={<div>waiting 200....</div>}>
<WaitingComponent wait={200} />
</Suspense>
<Suspense fallback={<div>waiting 300....</div>}>
<WaitingComponent wait={300} />
</Suspense>
<Suspense fallback={<div>waiting 400....</div>}>
<WaitingComponent wait={400} />
</Suspense>
<Suspense fallback={<div>waiting 500....</div>}>
<WaitingComponent wait={500} />
</Suspense>
<Suspense fallback={<div>waiting 600....</div>}>
<WaitingComponent wait={600} />
</Suspense>
<Suspense fallback={<div>waiting 700....</div>}>
<WaitingComponent wait={700} />
</Suspense>
</ul>
<div className="flex-col items-center justify-center border p-2">
<Suspense fallback={<Loading />}>
<WaitingComponent wait={800} />
<WaitingComponent wait={900} />
<WaitingComponent wait={1000} />
</Suspense>
</div>
</main>
);
}
'use client';
import { useSuspenseQuery } from '@tanstack/react-query';
function getBaseURL() {
if (typeof window !== 'undefined') {
return '';
}
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`;
}
return 'http://localhost:3000';
}
const baseUrl = getBaseURL();
function useWaitQuery(props: { wait: number }) {
const query = useSuspenseQuery({
queryKey: ['wait', props.wait],
queryFn: async () => {
const url = `${baseUrl}/api/wait?wait=${props.wait}`;
const res: string = await (
await fetch(url, {
cache: 'no-store',
})
).json();
return res;
},
});
return query;
}
export default function WaitingComponent(props: { wait: number }) {
const { data } = useWaitQuery(props);
return <li>result: {data}</li>;
}
첫 번째 코드는 페이지 코드이고, 두 번째 코드는 훅을 호출하는 비동기 컴포넌트이다.
Streaming을 사용하기 위해 따로 무언가 수정할 필요 없이 useQuery -> useSuspsenseQuery로만 바꾸면 Streaming을 사용할 수 있게 된다.
위와 같이 코드를 구성하게 되면 반환하는 초기 html은 아래와 같다.
<main>
<h1>React Query Test</h1>
<ul>
<!--$?-->
<template id="B:0"></template>
<div>waiting 100....</div>
<!--/$-->
<!--$?-->
...
다른 비동기 처리를 기다리지 않고 초기 html에 Suspense 밖에 있는 jsx들과 fallback 안에 있는 jsx들이 포함되는 걸 볼 수 있다.
또, 최근에 개발되는 대부분의 웹페이지들 내에서 로딩바, 스켈레톤과 같은 컴포넌트는 거의 필수시되고 있는데,
이를 직접 매 컴포넌트마다 개발하게 되면 유지 보수측면에서도 좋지 않은데, Suspense Hook을 사용하면 조금 더 깔끔하게 코드를 구성할 수 있을 것 같다는 생각이 든다.
'front-end > next.js' 카테고리의 다른 글
Next.js 15 RC 발표 (0) | 2024.05.24 |
---|---|
next.js 14.1 SSRF 취약점 노출 (0) | 2024.05.11 |
Next.js 14 소개 (0) | 2023.10.30 |
Server Components 활용하는 방법 (0) | 2023.10.12 |
Next.js 13.5 (2) | 2023.10.11 |

이전에도 언급한 적이 있지만 React Query는 정말 좋은 비동기 처리 라이브러리이다.
하지만 Suspense와의 연동성이 좋지 않아 최근에는 자주 사용하지 않고 있었다.
저번 달에 React Query v5가 출시되었다.
이 버전에는 Suspense와의 연동은 물론이고 Next.js의 Streaming과의 연동성도 매우 좋아졌다.
이번 글에서는 React Query v5의 주요 변경점과 함께 Next.js과는 어떻게 연결 지어야 하는지 다뤄보려고 한다.
One Function One Parameter

React Query에 있는 모든 Hook, Method들은 이제 하나의 Parameter를 갖게된다.
여러 개의 Parameter를 갖던 경우에는 Object 형태로 받을 수 있게 바뀌었다.
이 부분은 codemon을 통해 마이그레이션 가능하다고 가이드되고 있다.
Callback options are deprecated
query에는 onSuccess, onError와 같은 Callback 함수를 옵션으로 제공하였다.
v5에서는 이 부분을 Query의 일관성을 위해 제거시켰다고 한다.
(사실 좀 자주 사용하던 옵션인데 이 옵션이 편하기는 하지만 이 옵션이 유지 보수 측면에서 헷갈리게 만든다는 점은 어느 정도 동의를 하고 있었는데 제거될 것이라고는 생각도 못했다)
Etc..
- TypeScript 4.7+ for 타입 추론
- Error Type: unknown -> Error
- cacheTime -> gcTime (기능은 바뀌지 않음)
With Next.js
Next.js에서는 Streaming이라는 기술을 통해 사용자 경험을 향상시킨다.
이 글을 참고하면 좋을 것 같은데, 간단히 요약하면 Suspense 문법을 사용해 모든 컴포넌트가 로딩되기 이전에 다른 UI와 상호작용할 수 있게 해주는 기술이다.
Streaming 기술을 사용하기 위해 다양한 방법들이 있지만, React Query v5에서 정식으로 지원하는 문법인 useSuspenseQuery를 사용하면 더 쉽게 구현할 수 있다.
예시 코드와 함께 설명하면 좋을 것 같은데
import Loading from '@components/ui/loading';
import { Suspense } from 'react';
import WaitingComponent from './wating-component';
export const runtime = 'edge'; // 'nodejs' (default) | 'edge'
export default function ReactQueryExample() {
return (
<main>
<h1>React Query Test</h1>
<ul>
<Suspense fallback={<div>waiting 100....</div>}>
<WaitingComponent wait={100} />
</Suspense>
<Suspense fallback={<div>waiting 200....</div>}>
<WaitingComponent wait={200} />
</Suspense>
<Suspense fallback={<div>waiting 300....</div>}>
<WaitingComponent wait={300} />
</Suspense>
<Suspense fallback={<div>waiting 400....</div>}>
<WaitingComponent wait={400} />
</Suspense>
<Suspense fallback={<div>waiting 500....</div>}>
<WaitingComponent wait={500} />
</Suspense>
<Suspense fallback={<div>waiting 600....</div>}>
<WaitingComponent wait={600} />
</Suspense>
<Suspense fallback={<div>waiting 700....</div>}>
<WaitingComponent wait={700} />
</Suspense>
</ul>
<div className="flex-col items-center justify-center border p-2">
<Suspense fallback={<Loading />}>
<WaitingComponent wait={800} />
<WaitingComponent wait={900} />
<WaitingComponent wait={1000} />
</Suspense>
</div>
</main>
);
}
'use client';
import { useSuspenseQuery } from '@tanstack/react-query';
function getBaseURL() {
if (typeof window !== 'undefined') {
return '';
}
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`;
}
return 'http://localhost:3000';
}
const baseUrl = getBaseURL();
function useWaitQuery(props: { wait: number }) {
const query = useSuspenseQuery({
queryKey: ['wait', props.wait],
queryFn: async () => {
const url = `${baseUrl}/api/wait?wait=${props.wait}`;
const res: string = await (
await fetch(url, {
cache: 'no-store',
})
).json();
return res;
},
});
return query;
}
export default function WaitingComponent(props: { wait: number }) {
const { data } = useWaitQuery(props);
return <li>result: {data}</li>;
}
첫 번째 코드는 페이지 코드이고, 두 번째 코드는 훅을 호출하는 비동기 컴포넌트이다.
Streaming을 사용하기 위해 따로 무언가 수정할 필요 없이 useQuery -> useSuspsenseQuery로만 바꾸면 Streaming을 사용할 수 있게 된다.
위와 같이 코드를 구성하게 되면 반환하는 초기 html은 아래와 같다.
<main>
<h1>React Query Test</h1>
<ul>
<!--$?-->
<template id="B:0"></template>
<div>waiting 100....</div>
<!--/$-->
<!--$?-->
...
다른 비동기 처리를 기다리지 않고 초기 html에 Suspense 밖에 있는 jsx들과 fallback 안에 있는 jsx들이 포함되는 걸 볼 수 있다.
또, 최근에 개발되는 대부분의 웹페이지들 내에서 로딩바, 스켈레톤과 같은 컴포넌트는 거의 필수시되고 있는데,
이를 직접 매 컴포넌트마다 개발하게 되면 유지 보수측면에서도 좋지 않은데, Suspense Hook을 사용하면 조금 더 깔끔하게 코드를 구성할 수 있을 것 같다는 생각이 든다.
'front-end > next.js' 카테고리의 다른 글
Next.js 15 RC 발표 (0) | 2024.05.24 |
---|---|
next.js 14.1 SSRF 취약점 노출 (0) | 2024.05.11 |
Next.js 14 소개 (0) | 2023.10.30 |
Server Components 활용하는 방법 (0) | 2023.10.12 |
Next.js 13.5 (2) | 2023.10.11 |