๐ŸŽ‰ berenickt ๋ธ”๋กœ๊ทธ์— ์˜จ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ‰
Front
Tanstack Query
07-Queries

Queries

1. Query Basics

query๋Š” (unique key์™€ ๊ฒฐํ•ฉ๋œ,) (๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค์—) ์„ ์–ธ์  ์ข…์†์„ฑ์ด๋‹ค. ํ”„๋กœ๋ฏธ์Šค ๊ธฐ๋ฐ˜์˜ method(GET, POST)๋กœ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ data๋ฅผ fetchํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค๋ฉด, Mutations๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

๋„ˆ์˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ ์ปค์Šคํ…€ ํ›…์—์„œ query๋ฅผ ๊ตฌ๋…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ์ตœ์†Œํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด useQuery๋ฅผ ํ˜ธ์ถœํ•ด๋ผ.

  • query๋ฅผ ์œ„ํ•œ unique key
  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
    • resolves the data, or
    • throws an error
1
import { useQuery } from '@tanstack/react-query'
2
3
function App() {
4
const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
5
}

๋„ˆ๊ฐ€ ์ œ๊ณตํ•˜๋Š” unique key๋Š” ๋„ˆ์˜ query๋“ค์ด ์•ฑ ์ „์ฒด์—์„œ refetching, caching, sharingํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

useQuery์—์„œ ๋ฐ˜ํ™˜๋œ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์—๋Š” () ํฌํ•จ๋˜์–ด ์žˆ๋‹ค. (ํ…œํ”Œ๋ฆฟ์— ํ•„์š”ํ•œ query ๋ฐ ๊ธฐํƒ€ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด๊ฐ€,):

1
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })

result ๊ฐ์ฒด์—๋Š” ๋ช‡๊ฐ€์ง€ ์ƒ์‚ฐ์„ฑ์„ ์œ„ํ•œ ์•„์ฃผ ์ค‘์š”ํ•œ ์ƒํƒœ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค. query๋Š” ์ฃผ์–ด์ง„ ์ˆœ๊ฐ„(given moment)์— ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜์˜ ์ƒํƒœ๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

  • isLoading or status === 'loading' - ์ฟผ๋ฆฌ์— ์•„์ง ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š”
  • isError or status === 'error' - ์ฟผ๋ฆฌ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ
  • isSuccess or status === 'success' - ์ฟผ๋ฆฌ๊ฐ€ ์„ฑ๊ณตํ–ˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์œ„์™€ ๊ฐ™์€ ์ฃผ์š”ํ•œ ์ƒํƒœ ๋ง๊ณ ๋„, ์ฟผ๋ฆฌ ์ƒํƒœ์— ๋”ฐ๋ผ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • error - query๊ฐ€ isError ์ƒํƒœ๋ฉด, error ์†์„ฑ์„ ํ†ตํ•ด ์˜ค๋ฅ˜๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • data - query๊ฐ€ isSuccess ์ƒํƒœ๋ฉด, data ์†์„ฑ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • isFetching - ์–ด๋–ค ์ƒํƒœ์ด๋“ , query๊ฐ€ ์–ธ์ œ๋“ ์ง€ fetch ์ค‘์ด๋ฉด(background refetching ํฌํ•จํ•ด์„œ), isFetching์ด true๊ฐ€ ๋จ

๋Œ€๋ถ€๋ถ„์˜ query์˜ ๊ฒฝ์šฐ, ์ผ๋ฐ˜์ ์œผ๋กœ isPending ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์ถฉ๋ถ„ํ•˜๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, isError ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ , ๊ทธ ๋‹ค์Œ ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ , ์„ฑ๊ณต ์ƒํƒœ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค:

1
function Todos() {
2
const { isPending, isError, data, error } = useQuery({
3
queryKey: ['todos'],
4
queryFn: fetchTodoList,
5
})
6
7
if (isPending) {
8
return <span>Loading...</span>
9
}
10
11
if (isError) {
12
return <span>Error: {error.message}</span>
13
}
14
15
// We can assume by this point that `isSuccess === true`
16
return (
17
<ul>
18
{data.map(todo => (
19
<li key={todo.id}>{todo.title}</li>
20
))}
21
</ul>
22
)
23
}

๋งŒ์•ฝ booleans์ด ๋„ค ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด, ๋„ˆ๋Š” ํ•ญ์ƒ status ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค:

1
function Todos() {
2
const { status, data, error } = useQuery({
3
queryKey: ['todos'],
4
queryFn: fetchTodoList,
5
})
6
7
if (status === 'pending') {
8
return <span>Loading...</span>
9
}
10
11
if (status === 'error') {
12
return <span>Error: {error.message}</span>
13
}
14
15
// also status === 'success', but "else" logic works, too
16
return (
17
<ul>
18
{data.map(todo => (
19
<li key={todo.id}>{todo.title}</li>
20
))}
21
</ul>
22
)
23
}

๋˜ํ•œ TypeScript๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ขํžŒ๋‹ค. ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์—, pending ๋ฐ error๋ฅผ ํ™•์ธํ–ˆ๋‹ค๋ฉด,


2. FetchStatus(fetch ์ƒํƒœ๋“ค)

status ํ•„๋“œ ์™ธ์—๋„, ์ถ”๊ฐ€์ ์œผ๋กœ ๋‹ค์Œ์˜ ์˜ต์…˜๋“ค์„ ์ง€๋‹Œ fetchStatus ์†์„ฑ๋„ ์žˆ๋‹ค.

  • fetchStatus === 'fetching' - query๊ฐ€ ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์ค‘
  • fetchStatus === 'paused' - query๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค ํ–ˆ์ง€๋งŒ, ์ผ์‹œ์ค‘์ง€๋จ. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋„คํŠธ์›Œํฌ ๋ชจ๋“œ ํŽ˜์ด์ง€ ์ฐธ๊ณ 
  • fetchStatus === 'idle' - query๊ฐ€ ํ˜„์žฌ ์•„๋ฌด ์ž‘์—…๋„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Œ

3. ์™œ ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ 2๊ฐœ๋ƒ?

๋ฐฑ๊ทธ๋ผ์šด๋“œ refetches์™€ ์˜ค๋ž˜๋œ ๊ฒ€์ฆ ๋กœ์ง์€ ๋ชจ๋“  status์™€ fetchStatus์„ ์œ„ํ•œ ์กฐํ•ฉ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด:

  • success ์ƒํƒœ์˜ query๋Š” ์ผ๋ฐ˜์ ์œผ๋ก  idle fetchStatus์ด์ง€๋งŒ, ๋ฐฑ๊ทธ๋ผ์šด๋“œ refetch๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๋•Œ, fetching์—๋„ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋งˆ์šดํŠธ๋˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” query๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ pending๊ณผ fetching fetchStatus์ง€๋งŒ, ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์ด ์—†๋Š” ๊ฒฝ์šฐ paused๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๊ณ ๋„, query๊ฐ€ pending ์ƒํƒœ์— ์žˆ์„ ์ˆ˜ ์žˆ์Œ์„ ๋ช…์‹ฌํ•˜์ž!

  • status๋Š” data์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€?
  • fetchStatus๋Š” queryFn์˜ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ง€๊ธˆ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ์•„๋‹Œ์ง€?

4. ๋” ์•Œ์•„๋ณด๊ธฐ

์ƒํƒœ ํ™•์ธ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค