๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Frontend/TanStack Query

(8)
Dependent Queries useQuery dependent Query์ข…์†(๋˜๋Š” ์ˆœ์ฐจ์ ) ์ฟผ๋ฆฌ๋Š” ์ด์ „ ์ฟผ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์–ด์•ผ๋งŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๋‹ค. // ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐconst { data: user } = useQuery({ queryKey: ['user', email], queryFn: getUserByEmail,})const userId = user?.id// ์‚ฌ์šฉ์ž์˜ ํ”„๋กœ์ ํŠธ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐconst { status, fetchStatus, data: projects,} = useQuery({ queryKey: ['projects', userId], queryFn: getProjectsByUser, // userId๊ฐ€ ์กด์žฌํ•  ๋•Œ๊นŒ์ง€ ์ฟผ๋ฆฌ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. enabl..
Parallel Queries "Parallel"(๋ณ‘๋ ฌ) ์ฟผ๋ฆฌ๋Š” fetching ๋™์‹œ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ‘๋ ฌ๋กœ, ์ฆ‰ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ์ฟผ๋ฆฌ์ด๋‹ค. Manual Parallel Queries: ์ˆ˜๋™ ๋ณ‘๋ ฌ ์ฟผ๋ฆฌ๋ณ‘๋ ฌ ์ฟผ๋ฆฌ์˜ ์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ณ‘๋ ฌ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๋ณ„๋‹ค๋ฅธ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. TanStack Query์˜ useQuery ๋ฐ useInfiniteQuery ํ›…์„ ์›ํ•˜๋Š” ๋งŒํผ ๋‚˜๋ž€ํžˆ ์‚ฌ์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. function App () { // ๋‹ค์Œ ์ฟผ๋ฆฌ๋“ค์€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋œ๋‹ค const usersQuery = useQuery({ queryKey: ['users'], queryFn: fetchUsers }) const teamsQuery = useQuery({ queryKey: ['teams'], queryFn: fet..
Network Mode TanStack Query์˜ ๋„คํŠธ์›Œํฌ ๋ชจ๋“œ๋Š” ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ์ด ์—†์„ ๋•Œ ์ฟผ๋ฆฌ์™€ ๋ฎคํ…Œ์ด์…˜์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” 3๊ฐ€์ง€ ์„ค์ •์„ ์ œ๊ณตํ•œ๋‹ค. ์ด ๋ชจ๋“œ๋Š” ๊ฐ ์ฟผ๋ฆฌ/๋ฎคํ…Œ์ด์…˜์— ๊ฐœ๋ณ„์ ์œผ๋กœ ์„ค์ •ํ•˜๊ฑฐ๋‚˜, ๊ธฐ๋ณธ๊ฐ’์„ ํ†ตํ•ด ์ „์—ญ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ํŒจ์นญ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ๋ชจ๋“œ๋Š” online์ด๋‹ค. Network Mode: online์ด ๋ชจ๋“œ์—์„œ๋Š” ์ธํ„ฐ๋„ท์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์„ ๋•Œ๋งŒ ์ฟผ๋ฆฌ์™€ ๋ฎคํ…Œ์ด์…˜์ด ์‹คํ–‰๋œ๋‹ค. ์ด๊ฒƒ์ด ๊ธฐ๋ณธ๊ฐ’์ด๋‹ค. ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ์ด ์—†์–ด ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ์ฟผ๋ฆฌ๋Š” ๊ธฐ์กด์˜ state(pending, error, success) ์ƒํƒœ๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋•Œ fetchStatus๋ผ๋Š” ์ถ”๊ฐ€์ ์ธ ์ƒํƒœ๊ฐ€ ์ œ๊ณต๋˜์–ด ๋” ์ž์„ธํ•œ ์ƒํ™ฉ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.fetching: ..
Query Options queryKey์™€ queryFn์„ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ๊ณต์œ ํ•˜๋ฉด์„œ๋„ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ํ•œ ๊ณณ์— ๋ชจ์•„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋Š” queryOptions helper๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋Ÿฐํƒ€์ž„ ์‹œ ์ด ํ—ฌํผ๋Š” ์ „๋‹ฌ๋ฐ›์€ ์˜ต์…˜ ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•  ๋ฟ์ด์ง€๋งŒ, TypeScript์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ˆ˜๋งŽ์€ ์ด์ ์„ ์ œ๊ณตํ•œ๋‹ค. ์ฟผ๋ฆฌ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์˜ต์…˜์„ ํ•œ ๊ณณ์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด type inference(ํƒ€์ž… ์ถ”๋ก )๊ณผ type safety(ํƒ€์ž… ์•ˆ์ •์„ฑ)์„ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณด์žฅ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.import { queryOptions } from '@tanstack/react-query'function groupOptions(id: number) { return queryOptions({ queryKey: ['gro..
Query Functions ์ฟผ๋ฆฌ ํ•จ์ˆ˜๋Š” promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด promise๋Š” ๋ฐ์ดํ„ฐ๋ฅผ reslove(์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ)ํ•˜๊ฑฐ๋‚˜ ์—๋Ÿฌ๋ฅผ throwํ•ด์•ผ ํ•œ๋‹ค. ๋‹ค์Œ์€ ๋ชจ๋‘ ์œ ํšจํ•œ ์ฟผ๋ฆฌ ํ•จ์ˆ˜ ์„ค์ •์˜ ์˜ˆ์‹œ์ด๋‹ค.useQuery({ queryKey: ['todos'], queryFn: fetchAllTodos })useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) })useQuery({ queryKey: ['todos', todoId], queryFn: async () => { const data = await fetchTodoById(todoId) return data }, }) useQuery({ ..
Query Keys TanStack Query์˜ ํ•ต์‹ฌ์€ ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ ์บ์‹ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฟผ๋ฆฌ ํ‚ค๋Š” ๋ฐ˜๋“œ์‹œ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ๋ฐฐ์—ด์ด์–ด์•ผ ํ•œ๋‹ค. ['todos']์ฒ˜๋Ÿผ ๋‹จ์ผ ๋ฌธ์ž์—ด์„ ๊ฐ€์ง„ ๊ฐ„๋‹จํ•œ ๋ฐฐ์—ด์ผ ์ˆ˜๋„ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ๋ฌธ์ž์—ด๊ณผ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•˜๋Š” ๋ณต์žกํ•œ ๋ฐฐ์—ด์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ์ฟผ๋ฆฌ ํ‚ค๊ฐ€ JSON.stringfy๋กœ ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•˜๊ณ  ํ•ด๋‹น ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด ์–ด๋–ค ํ˜•ํƒœ๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. Simple Query Keys๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ ํ‚ค๋Š” ์ƒ์ˆ˜ ๊ฐ’์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด์ด๋‹ค. ์ด ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค.์ผ๋ฐ˜์ ์ธ ๋ชฉ๋ก/์ธ๋ฑ์Šค ๋ฆฌ์†Œ์Šค๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์—†๋Š” ๋ฆฌ์†Œ์Šค// A list of todosuseQuery({ queryKey: ['todos'], ... })// Something els..
Queries ์ฟผ๋ฆฌ๋Š” ๊ณ ์œ ํ•œ ํ‚ค์— ์—ฐ๊ฒฐ๋œ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ๋Œ€ํ•œ ์„ ์–ธ์  ์˜์กด์„ฑ์ด๋‹ค. ์ฟผ๋ฆฌ๋Š” Promise๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ•จ์ˆ˜(GET, POST ๋ฉ”์„œ๋“œ ํฌํ•จ)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Mutations๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋‚˜ ์ปค์Šคํ…€ ํ›…์—์„œ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, useQuery ํ›…์„ ์ตœ์†Œํ•œ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ธ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.์ฟผ๋ฆฌ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ ํ•œ ํ‚ค๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™€ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ดimport { useQuery } from '@tanstack/react-query'function App() { const info = useQuery({ query..
์™œ TanStack Query๋ฅผ ์‚ฌ์šฉํ• ๊นŒ? TanStack Query๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ผญ ํ•„์š”ํ–ˆ๋˜ data-fetching ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์™„์„ฑํŒ์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ๊ธฐ์ˆ ์ ์œผ๋กœ ๋งํ•˜๋ฉด, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์บ์‹ฑํ•˜๋ฉฐ, ๋™๊ธฐํ™”ํ•˜๊ณ , ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ž‘์—…์„ ์•„์ฃผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ์™œ ํ•„์š”ํ• ๊นŒ?๋Œ€๋ถ€๋ถ„์˜ ํ•ต์‹ฌ ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ํ†ตํ•ฉ์ ์ด๊ณ  ์ •ํ˜•ํ™”๋œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋“ค์€ ๋ฐ์ดํ„ฐ ํŽ˜์นญ์— ๋Œ€ํ•œ ์—„๊ฒฉํ•œ ๊ทœ์น™์„ ํฌํ•จํ•˜๋Š” ๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, ์ž์‹ ๋งŒ์˜ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ๋ฐฉ์‹์„ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค. ์ด๋Š” ๋ณดํ†ต ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์—ฎ๊ฑฐ๋‚˜, Redux๋‚˜ Zustand ๊ฐ™์€ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ์•ฑ ์ „์ฒด์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ท€๊ฒฐ๋œ๋‹ค. ์ „ํ†ต์ ์ธ ..