์ค์ ๋ก ์๋ฒ๋ฅผ ์ด์ํ ์๊ฐ์ด๊ธฐ์
์๋ฒ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํด
TanStackQuery ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฃ์ด๋ณผ ์๊ฐ์ด๋ค.
https://lotto-magic-frontend.vercel.app/
๋ก๋ ๋ฒํธ ์์ฑ ๋ง๋ฒ์ง
ํ์ด ์์ 3๊ฐ๋ฅผ ์ ํํ๋ฉด ์ค๋์ ๋ก๋ ๋ฒํธ์ ํ์ด ์ ์๋ฅผ ๋ง๋ค์ด์ฃผ๋ ์ฌ์ดํธ์ ๋๋ค.
lotto-magic-frontend.vercel.app
1. TanStackQuery
- ์๋ฒ์์ ๋ฐ์์ค๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
- ๊ทธ ์ธ ๋ฐ์ดํฐ ์บ์ฑ, ์บ์ ์ ์ด ๋ฑ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ํจ์จ์ ์ด๊ฒ ๊ด๋ฆฌํด์ค๋ค.
- React Query๋ผ๋ ์ด๋ฆ์ผ๋ก ์์ํ์ง๋ง v4๋ถํฐ Vue๋ Svelte ๋ฑ์ ๋ค๋ฅธ ํ๋ ์์ํฌ์์๋ ํ์ฉํ ์ ์๋๋ก ๊ธฐ๋ฅ์ด ํ์ฅ๋๋ฉฐ TanStack Query๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ๋์๋ค.
- ๋ํ์ ์ธ ๊ธฐ๋ฅ์ผ๋ก ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ ์บ์ฑ | ๋์ผ ์์ฒญ์ ์ค๋ณต ์ ๊ฑฐ | ์ ์ ํ ๋ฐ์ดํฐ ์ ์ง | ๋ฌดํ ์คํฌ๋กค, ํ์ด์ง๋ค์ด์ ๋ฑ์ ์ฑ๋ฅ ์ต์ ํ | ๋คํธ์ํฌ ์ฌ์ฐ๊ฒฐ, ์์ฒญ ์คํจ ๋ฑ์ ์๋ ๊ฐฑ์ ์ด ์๋ค.
- ๋ฐ์ดํฐ ์บ์ฑ
: TanStack Query๋ฅผ ํ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋๋ ํญ์ ์ฟผ๋ฆฌ ํค(queryKey)๋ฅผ ์ง์ ํ๊ฒ ๋๋ค. ์ฟผ๋ฆฌ ํค์ ์ผ์นํ๋ ์บ์๋ ๋ฐ์ดํฐ๊ฐ ์์ ๋, ์๋ฒ์์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค. ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉด ๊ทธ ๋ฐ์ดํฐ๋ ์บ์๋๊ณ ๊ทธ ์ดํ ์์ฒญ๋ถํฐ๋ ๊ฐ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๋ฐ๋๋ก ์ผ์นํ๋ ์บ์๋ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ์๋ฒ์ ์์ฒญํ์ง ์๊ณ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ค. ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์์ฒญ์ด ์ฌ๋ฌ ๋ฒ ๋ฐ์ํด๋, ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ฒ ๋์ด ์ค๋ณต ์์ฒญ์ ์ค์ผ ์ ์๋ค. - ๋ฐ์ดํฐ์ ์ ์ ๋
: TanStack Query๋ ์บ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ (Fresh)ํ๊ฑฐ๋ ์ํ(Stale) ์ํ๋ก ๊ตฌ๋ถํด ๊ด๋ฆฌํ๋ค. ์บ์๋ ๋ฐ์ดํฐ๊ฐ ์ ์ ํ๋ค๋ฉด ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ณ , ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ์ํ๋ค๋ฉด ์๋ฒ์ ๋ค์ ์์ฒญํด ์ ์ ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค. ๋ฐ์ดํฐ๊ฐ ์ํ๋ ๋ฐ๊น์ง ๊ฑธ๋ฆฌ๋ ์๊ฐ์ staleTime ์ต์ ์ผ๋ก ์ง์ ํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ ํ์ง ์ํ๋์ง ์ฌ๋ถ๋ isStale๋ก ํ์ธํ ์ ์๋ค. - ํ์ฌ ์งํํ๊ณ ์๋ ํ๋ก์ ํธ ๊ธฐ์ค์ผ๋ก MSW๋ ๋ฐฑ์๋ API์์ ๋ฐ์์ค๋ ๋ฐ์ดํฐ๊ฐ ์์ ๋ TanStack Query๋ฅผ ํตํด, ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ | ๋ก๋ฉ ์ํ ๊ด๋ฆฌ | ์๋ฌ ์ํ ๊ด๋ฆฌ | ์บ์ฑ | ๋ค์ ์์ฒญํ๊ธฐ ๋ฑ์ ๋์ ํ๊ฒ ํ ์ ์๋ค.
2. ์ฝ๋ ๋น๊ต๋ก ๋ณด๋ ํ์์ฑ
- TanStackQuery (X)
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/result')
.then((res) => res.json())
.then((data) => {
setData(data);
setIsLoading(false);
})
.catch((err) => {
setError(err);
setIsLoading(false);
});
}, []);
์์ ์ฝ๋๋ฅผ ๊ฐ๋จํ ์ค๋ช ํด๋ณด๊ฒ ๋ค. data: null, isLoading: true, error: null ์ํ๋ก ํ๋ฉด์ด ๊ทธ๋ ค์ง๋ค. ๊ทธ๋ฆฌ๊ณ useEffect๊ฐ ์คํ๋๋ฉด์ ๋ฐฑ์๋์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ค. ์ฒซ๋ฒ์งธ then์์ ์๋ต์ JSON ํํ๋ก ๋ฐํํ๋ค. ๋๋ฒ์งธ then์์ ๋ณํ๋ ๋ฐ์ดํฐ๋ฅผ setData์ ๋ฃ๊ณ , setIsLoading(false)๋ฅผ ํธ์ถํด ๋ก๋ฉ์ด ๋๋ฌ์์ ์๋ฆฐ๋ค. catch๋ก ๋คํธ์ํฌ ์ค๋ฅ๋ ์๋ฒ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด error ์ํ์ ์๋ฌ ๋ด์ฉ์ ์ ์ฅํ๊ณ ๋ก๋ฉ์ ์ข ๋ฃํ๋ค.
ํ๋ก์ ํธ๊ฐ ์ปค์ง๋ฉด ์์ ์ฝ๋์ฒ๋ผ ๋ก๋ฉ ์ํ, ์๋ฌ ์ํ๋ฅผ ๋งค๋ฒ ์ง์ ๋ง๋ค์ด์ค์ผํ๋ค. ๊ทธ๋์ TanStackQuery๋ฅผ ์จ์ ์์ ์ฝ๋๋ฅผ ํจ์ฌ ๊ฐ๋จํ๊ฒ ๋ง๋ค ์ ์๋ค.
- TanStackQuery (O)
const { data, isLoading, isError } = useQuery({
queryKey: ['result'],
queryFn: getResult,
});
data๋ ์๋ฒ์์ ๋ฐ์์จ ๋ฐ์ดํฐ๊ฐ ๋๋ค. isLoading์ ๋ก๋ฉ ์ค์ธ์ง๋ฅผ ๋ํ๋ธ๋ค. isError๋ ์๋ฌ๊ฐ ๋ฌ๋์ง๋ฅผ ๋ํ๋ธ๋ค. querKey๋ ์ด ๋ฐ์ดํฐ์ ์ด๋ฆํ๊ณ queryFn์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์๊ฐ ๋๋ค.
TanStackQuery๋ฅผ ์ฌ์ฉํ์ง ์์๋ ์ฝ๋๋ useState๋ฅผ 3๊ฐ๋ ๋ง๋ค๊ณ fetch์ ์ฑ๊ณต,์คํจ ์์ ๋ง๋ค ์ผ์ผ์ด setํจ์๋ฅผ ํธ์ถํด์ค์ผ ํ๋ค. TanStackQuery๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ data, isLoading, isError ์ํ๋ฅผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ด๋ถ์ ์ผ๋ก ์์์ ๊ด๋ฆฌํ๊ณ ๊ฐ์ฒด ํํ๋ก ๋์ ธ์ค๋ค. ๊ฐ๋ฐ์๋ ๊ทธ๋ฅ ๋ฐ์์ ์ฐ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
TanStackQuery๋ฅผ ์ฌ์ฉํ์ง ์์๋ ์ฝ๋๋ ์ปดํฌ๋ํธ๊ฐ ๋ํ๋๋ฉด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ผ๋ ์์ ๋ช ๋ นํ ๋ฐฉ์์ด์๋ค. ๊ทธ๋ฌ๋ TanStackQuery๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ ์ด ๋ฐ์ดํฐ๋ result๋ผ๋ ํค๋ฅผ ๊ฐ์ง๊ณ getResult ํจ์๋ก ๊ฐ์ ธ์จ๋ค๊ณ ์ ์๋ง ํด๋๋ ์ ์ธ์ ๋ฐฉ์์ด๋ค.
useQuery๋ ๋์ผํ ํค(result) ์์ฒญ ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋ ๊ฐ์ ์ฆ์ ๋ฐํ(์บ์ฑ)ํ๊ณ ๋คํธ์ํฌ ์ฅ์ ์ ์๋์ผ๋ก ์ฌ๋ฌ ๋ฒ ์ฌ์๋๋ฅผ ํ๋ค. ๋ธ๋ผ์ฐ์ ์ฐฝ์ ๋ค์ ํฌ์ปค์คํ๊ฑฐ๋ ๋คํธ์ํฌ๊ฐ ์ฌ์ฐ๊ฒฐ๋ ๋ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฅผ ํ๊ณ ๋์ผํ API ์์ฒญ์ด ๋์์ ์ฌ๋ฌ ๊ฐ ๋ฐ์ํด๋ ํ ๋ฒ๋ง ํธ์ถํ๋ค.
3. TanStackQuery ์ค์น
- TanStackQuery ์ค์น ๋ช
๋ น์ด (npm์ ์ฌ์ฉ ์ค์ธ ๊ฒฝ์ฐ)

npm i @tanstack/react-query
- React Query Devtools ์ค์น (ํ์ ์๋)
npm i @tanstack/react-query-devtools
๊ฐ๋ฐ ์ค์ React Query๊ฐ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๊ณ ์๋์ง ๋์ผ๋ก ๋ณด๊ณ ์ถ๋ค๋ฉด Devtools๋ฅผ ์ค์นํ๋ฉด ๋๋ค. ์ด๋ ์ ํ์ฌํญ์ด๋ค!
4. TanStackQuery ์ฝ๋ ์์ฑ
- QueryProvider.tsx ํ์ผ ๋ง๋ค๊ธฐ

- QueryProvider ์ ์ฒด ์ฝ๋
'use client';
import { ReactNode, useState } from 'react';
import {
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
type QueryProviderProps = {
children: ReactNode;
};
export default function QueryProvider({ children }: QueryProviderProps) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 30,
retry: 1,
refetchOnWindowFocus: false,
},
mutations: {
retry: 0,
},
},
})
);
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
}
์ฑ ์ ์ฒด์์ React Query๋ฅผ ์ธ ์ ์๋๋ก QueryClientProvider๋ก ๊ฐ์ธ์ผ ํ๋ค. ๊ณต์ ๋ฌธ์์ ๋ณด๋ฉด QueryClient๋ฅผ ๋ง๋ค๊ณ , QueryClientProvider๋ก ๊ฐ์ธ๋ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ๋ฅ๋ก ์๋ดํ๋ค. ๊ธ ๋งจ ์๋์ ๋งํฌ๋ฅผ ์ฒจ๋ถํ๊ฒ ๋ค. ๊ทธ ์์ ๋ณด๋ฉด ๊ฐ์ ํ๋ก์ ํธ์ ๋ง์ถฐ์ ์ค์นํ ์ ์๊ฒ ๋ช ๋ น์ด๋ ์ ๋์์๋ค.
- ์ค๋ช ์ด ํฌํจ๋ ์ฝ๋
'use client';
import { ReactNode, useState } from 'react';
import {
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
type QueryProviderProps = {
// ์ปดํฌ๋ํธ์ ํ์ ์์๋ค์ ๋ฐ๊ธฐ ์ํ ํ์
์ ์
children: ReactNode;
};
export default function QueryProvider({ children }: QueryProviderProps) {
// QueryClient ์ธ์คํด์ค๋ฅผ useState๋ก ๊ด๋ฆฌ
// ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ๋๋ง๋ค ์๋ก์ด ํด๋ผ์ธํธ๊ฐ ์์ฑ๋๋ ๊ฒ์ ๋ง์์ค
// ์ด๊ธฐ๊ฐ ์์ฑ ํจ์ (() = new QueryClient)๋ฅผ ์ฌ์ฉํ์ฌ ๋ฑ ํ ๋ฒ๋ง ์์ฑ๋๋๋ก ํจ
const [queryClient] = useState(
() =>
new QueryClient({
// ์ ์ญ ๊ธฐ๋ณธ ์ต์
์ ์ค์
defaultOptions: {
queries: {
// ๋ฐ์ดํฐ๊ฐ ์ ์ ํ๋ค๊ณ ๊ฐ์ฃผ๋๋ ์๊ฐ (30์ด)
// ์ด ์๊ฐ ๋์์ ๋์ผํ ์ฟผ๋ฆฌ๋ฅผ ์์ฒญํ๋ฉด ์บ์๋ฅผ ์ฌ์ฉํจ
staleTime: 1000 * 30,
// ์์ฒญ ์คํจ ์ ์๋์ผ๋ก ์ฌ์๋ํ๋ ํ์, ํ๋ฒ๋ง ์๋ํจ
retry: 1,
// ๋ธ๋ผ์ฐ์ ํญ์ ๋ค์ ํด๋ฆญํ์ ๋ ๋ฐ์ดํฐ๋ฅผ ์๋ก๊ณ ์นจํ ์ง ์ ํ๋๋ฐ
// false๋ก ์ค์ ํด์ ๋คํธ์ํฌ ๋น์ฉ ์ค์
refetchOnWindowFocus: false,
},
// ๋ฐ์ดํฐ ์์ฑ, ์์ , ์ญ์ ์์ฒญ ์ ์ต์
์ผ๋ก
// ์๋ฌ ๋ฐ์ ์ ์ฌ์ฉ์์๊ฒ ๋ฐ๋ก ์๋ฆฌ๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํด์ ์ฌ์๋๋ฅผ 0์ผ๋ก ์ค์
mutations: {
retry: 0,
},
},
})
);
// Provider๋ก ํ์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ์ Queryclient๋ฅผ ๊ณต๊ธ
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
}
- layout.tsx
return (
<html lang="ko">
<body className={`${geistSans.variable} ${geistMono.variable}`}>
<MswProvider>
<QueryProvider>
{children}
</QueryProvider>
<MagicToaster />
</MswProvider>
</body>
</html>
);
}
{children}์ด QueryProvider์ ๊ฐ์ธ์ ธ ์๋ค. children์ ๋ณดํต ๊ฐ๋ฐ์๊ฐ ๋ง๋ ํ์ด์ง๋ฅผ ๋งํ๋ค. ์ง๊ธ ์ด ํ๋ก์ ํธ์์ ๋ฉ์ธํ์ด์ง, ๋ก๋ฉํ์ด์ง, ๊ฒฐ๊ณผ ํ์ด์ง๊ฐ children์ ๋ค์ด๊ฐ๋ค.
์ด children์ QueryProvider๋ก ๊ฐ์ธ์ผ userQuery( ), useMutation( ), useQueryClient( )๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
5. ๋ฉ์ธํ์ด์ง์ TanStackQuery ์ ์ฉํ๊ธฐ
- import
import { useMutation, useQuery } from '@tanstack/react-query';
- ์ ํ ์์ ๋ถ๋ฌ์ค๋ ์์ฒญ
const {
data: optionData,
isLoading: isLoadingOptions,
isError: isOptionError,
} = useQuery({
queryKey: ['lotto-options'],
queryFn: getLottoOptions,
});
ํ๋ฉด์ ํ์ด, ์กฐ์๋์ ๋์ ๋ฑ ์ฌ์ฉ์๊ฐ ์์๋ฅผ ์ ํํ ์ ์๋ ๊ตฌ๊ฐ์ด ์๋ค. ์ด๋ฐ ์์๋ค์ useQuery๋ก ๋ถ๋ฌ์ค๋๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค.
queryKey๋ ๋ฐ์ดํฐ์ ์ด๋ฆ์ผ๋ก ReactQuery๋ lotto-options๋ผ๋ ์ด๋ฆ์ผ๋ก ๊ด๋ฆฌํ๋ค. ์๊น ๋ฐ์ดํฐ์ ์ ์ ํ๋ค๊ณ ํ๋จํ๋ ์๊ฐ์ 30์ด๋ก ์ค์ ํ๋ค. 30์ด ์์ lotto-options ์์ฒญ์ด ๋ค์ด์ค๋ฉด React Query๋ ์๊น ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ผ๊ณ ํ๋จํ๊ณ ์บ์๊ฐ ์๋ ๊ฑธ ํ์ธํ ๋ค, ์ฌํ์ฉํ๋ค.
queryFn์ ์ค์ ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์๋ค. lotto-options ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋๋ getLottoOptions ํจ์๋ฅผ ์คํํ๋๋ก ์์ฑํ๋ค.
useQuery๋ ๊ฒฐ๊ณผ๋ก ์ฌ๋ฌ ์ํ๋ฅผ ์ค๋ค. ์๋ฒ์์ ์ง์ ๋ฐ์์ค๋ OptionData, ์ ํ ์์๋ฅผ ๊ฐ์ ธ์ค๋ ์ค์ธ์ง ์๋ ค์ฃผ๋ isLoadingOptions, ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ค๊ฐ ์๋ฌ๊ฐ ๋ฌ๋์ง ์๋ ค์ฃผ๋ isOptionsError๊ฐ ์๋ค.
- ๋ก๋ ๋ฒํธ ์์ฑ ์์ฒญ
const drawMutation = useMutation({
mutationFn: drawLottoNumbers,
onSuccess: (result) => {
sessionStorage.setItem('lotto-result', JSON.stringify(result));
router.push('/loading');
},
onError: (error) => {
const message =
error instanceof Error
? error.message
: '๊ฒฐ๊ณผ๋ฅผ ์์ฑํ์ง ๋ชปํ์ต๋๋ค.';
showMagicToast(message);
},
});
useMutation์ ์คํ, ๋ณ๊ฒฝ, ์์ฑ ์์ฒญ์ด๋ค. ์ฌ์ฉ์๊ฐ ์์ 3๊ฐ๋ฅผ ์ ํํ๊ณ ๋ง๋ค๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด ์คํ์ด ๋๋ค.
mutationFn์ ์ค์ ๋ก ์คํํ ํจ์๋ก, drawLottoNumbers ํจ์๊ฐ ์คํ๋๋ค.
onSuccess๋ ์์ฒญ์ด ์ฑ๊ณตํ๋ฉด ์คํ๋๋ ๋ถ๋ถ์ด๋ค. ๋ง์ฝ ์์ฒญ์ด ์ฑ๊ณตํ๋ฉด ๋ก๋ ๊ฒฐ๊ณผ๋ฅผ ๋ธ๋ผ์ฐ์ ์ sessionStorage์ ์ ์ฅํ๋ค. ์ ์ฅํ ๋ค ๋ฐ๋ก ๋ก๋ฉํ์ด์ง๋ก ๋ณด๋ด๊ณ ๊ฒฐ๊ณผํ์ด์ง์ ์ ์ฅํ ๊ฐ์ ๊บผ๋ด ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๋๋ก ๋ง๋ค์๋ค.
onError๋ ์์ฒญ์ด ์คํจํ๋ฉด ์คํ๋๋ ๋ถ๋ถ์ด๋ค. ์๋ฒ ์์ฒญ ์ค์ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ํ ์คํธ๋ก ์๋ฌ ๋ฉ์์ง๋ฅผ ๊บผ๋ด์ ๋ณด์ฌ์ค๋ค.
- ์ค์ ์คํ๋๋๋ก ํ๋ ์ฝ๋
const handleCreateClick = () => {
if (selectedOptions.length !== 3) {
showMagicToast('์์ 3๊ฐ์ง๋ฅผ ์ ํํด์ฃผ์ธ์.');
return;
}
drawMutation.mutate({
selectedOptions,
});
};
useMutation์ด ์ค์ ๋ก ์คํ๋๋ ๋ถ๋ถ์ด๋ค. if๋ฌธ์ ํต๊ณผํ๋ฉด drawlottoNumbers ํจ์์๊ฒ selectedOptions(์ ํํ ์์)๋ฅผ ๋๊ฒจ์ ์คํํ๋๋ก ์์ฑ๋ ์ฝ๋์ด๋ค. ์ฝ๊ฒ ์ค๋ช ํ์๋ฉด ์ฌ์ฉ์๊ฐ ์ ํํ ์์ 3๊ฐ๊ฐ API ํจ์๋ก ์ ๋ฌ๋๋ ๊ฒ์ด๋ค.
๋ง์ฝ ์ฌ์ฉ์๊ฐ ํ์ด, ๋ด๋, 1๋ฑ์ดํ์ํด๋ฅผ ์ ํํ๋ค๊ณ ๊ฐ์ ํ๋ค๋ฉด, mutate๋ก ๋์ด๊ฐ๋ ๊ฐ์ selectedOptions: ['ํ์ด', '๋ด๋', '1๋ฑ์ดํ์ํด']๊ฐ ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด drawLottoNumbers ํจ์๊ฐ ์ด ๊ฐ์ ๋ฐ์์ ๋ก๋ ๋ฒํธ ์์ฑ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค.
- ์ค๋ณต ๋ง๊ธฐ
<button
type="button"
className={styles.createButton}
onClick={handleCreateClick}
disabled={drawMutation.isPending}
>
{drawMutation.isPending ? (
<>
๊ฒฐ๊ณผ ์์ฑ
<br />
์ค...
</>
) : (
<>
์ฟต์ง์ฟต์ง
<br />
๋ง๋ค๊ธฐ
</>
)}
</button>
disabled={drawMutation.isPending}์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํด๋์๋ค. ํ์์๋ ์ฟต์ง์ฟต์ง ๋ง๋ค๊ธฐ๋ผ๋ ๋ฒํผ์ด ๋ณด์ด๊ฒ ์ง๋ง, ๋ก๋ ๋ฒํธ ์์ฑ ์ค์ด๋ฉด isPending(mutation์ด ์คํ ์ค์ธ์ง ์๋ ค์ฃผ๋ ์ํ)์ด true๊ฐ ๋๋ฉด์ ๊ฒฐ๊ณผ ์์ฑ ์ค์ด๋ผ๊ณ ๋ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฒํผ์ ๋๋ฆฌ์ง ์๊ฒ ๋๋ค.
Installation | TanStack Query React Docs
You can install React Query via , or a good ol' <script via . NPM bash npm i @tanstack/react-query or bash pnpm add @tanstack/react-query or bash yarn add @tanstack/react-query or bash bun add @tansta...
tanstack.com