React-Query ์žฅ์ ๐Ÿš€

๋ฆฌ์•กํŠธ์ฟผ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๊บผ๋‚ด๋ณธ๋‹ค,โ€ฆ ์™œ๋ƒ๋ฉด ์ข‹์€๊ฒƒ ๊ฐ™์€๋ฐ ์™œ ์ข‹์€์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ์ด๊ฑธ ์ซŒ ์•Œ๊ณ ์‹ถ์–ด์„œ ๋‹ค์‹œ ๊บผ๋ƒˆ๋‹ค. ํ•œ๋ฒˆ ์ž˜ ํŒŒ๋ณด์ž

React-query ๊ณตํ™ˆ

๐ŸŒบ ๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ

๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋Š” ๊ฝƒ์ด ์•„์ฃผ ๋งˆ์Œ์—๋“ ๋‹คโ€ฆ ใ…Žใ…Ž ์˜ˆ์ „์—๋Š” ๊ณตํ™ˆ์— ๊ฝƒ ๋กœ๊ทธ๊ฐ€ ๋ฐ•ํžŒ ๊น”๋”ํ•˜๊ณ  ์˜ˆ์œ ์‚ฌ์ดํŠธ์˜€๋Š”๋ฐ, ์ง€๊ธˆ์€ ๋ฒ„์ „์ด ๋ฐ”๋€Œ๋ฉด์„œ tanstack์˜ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ค๊ณผ ํ•ฉ์ณ์กŒ๋‹น. ์•„๋ฌดํŠผ ๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋Š” Fetching, ๋™๊ธฐํ™”, ์บ์‹ฑ, ์„œ๋ฒ„ ์ชฝ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ ๋“ฑ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” React ๊ธฐ๋ฐ˜์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. state(์ƒํƒœ)๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” Redux, Zustand, Recoil ๋“ฑ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ๋ฆฌ์•กํŠธ์ฟผ๋ฆฌ๊ฐ€ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ํฐ ์ธ๊ธฐ๋ฅผ ๋ฐ›๋Š” ์ด์œ ๋Š”, **์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. **

๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ์˜ ์›๋ฆฌ์™€ ์žฅ์ ์— ๋Œ€ํ•ด์„œ ์•Œ๋ ค๋ฉด, ์šฐ์„  Server State ์™€ Client State์˜ ์ฐจ์ด์— ๋Œ€ํ•ด์„œ ์•Œ์•„์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.

โ— Client State VS Server State

โ—พ Server State

์„œ๋ฒ„ ์ƒํƒœ๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ์ดํ„ฐ์ด๋‹ค.

  1. ์„ธ์…˜๊ฐ„์˜ ์ง€์†๋˜๋Š” ๋ฐ์ดํ„ฐ
  2. ํด๋ผ์ด์–ธํŠธ๋งŒ ์†Œ์œ ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ ๊ณต์œ ๋˜๋Š” ๋ฐ์ดํ„ฐ๋„ ์กด์žฌํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์— ์˜ํ•ด ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์Œ.
  3. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์— ์˜ํ•ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ์ง€์†์ ์ธ ๋ฐ์ดํ„ฐ์ด๋ฉฐ, ๋น„๋™๊ธฐ ์š”์ฒญ์— ์˜ํ•ด ํŒจ์น˜์™€ ์—…๋ฐ์ดํŠธ, delete๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

โ—พ Client State

ํด๋ผ์ด์–ธํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋™๊ธฐ์ ์ด๋ฉฐ, ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜๋Š” ํ•ญ์ƒ ์ตœ์‹ ์˜ ์ƒํƒœ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฒ„ํŠผ์„ ์—ด๊ณ  ๋‹ซ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” useState ๋‚˜ Zustand, Recoil,Redux๋“ฑ์ด ํด๋ผ์ด์–ธํŠธ์— ์ „์—ญ์ ์ธ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋‹ค.

โ› React-query๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ๊ณ„๊ธฐ

Client State์™€ Server State๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜ค๋Š” ์„œ๋ฒ„ State๋Š” ํ•ญ์ƒ ์ตœ์‹ ์ƒํƒœ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ง€๊ธˆ ํ˜„์žฌ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ ํŒจ์นญํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณด๋ฉด, ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ useState๋‚˜ ๋‹ค๋ฅธ ์ „์—ญ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ €์žฅํ•ด ๋†“์€ ๋‹ค์Œ์— ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด, ์„œ๋ฒ„์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ, ๊ฐ•์ œ ๋ฆฌํ”„๋ ˆ์‰ฌ๋ฅผ ํ•˜๊ฑฐ๋‚˜, state๋ฅผ ๋ณ€ํ™”์‹œ์ผœ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•œ๋‹ค. ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์€ ์ตœ์†Œํ•œ์œผ๋กœ ์ค„์ด๋Š”๊ฒŒ ์ข‹์€๋ฐ, ๋ณต์ˆ˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด fetching์„ ์—ฌ๋Ÿฌ๋ฒˆ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ๋‚ญ๋น„๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ store ๋‚ด๋ถ€์— ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ state๊ฐ€ ๊ณต์กดํ•˜๊ฒŒ ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ๋ฒ„์—์„œ ์ด๋ฏธ ํŒจ์น˜๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ํŒจ์น˜๋˜๊ธฐ ์ „ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ €์—๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ๋„ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•ด ๋„คํŠธ์›Œํฌ์˜ ๋ถˆํ•„์š”ํ•œ ์š”์ฒญ์„ ์ค„์ด๊ณ , ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ state๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉฐ, ๋ณด๋‹ค ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์š”์ฒญ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด (?) ๋งŒ๋“ค์–ด ์กŒ๋‹ค.

๐Ÿ‘€ React-query ์žฅ์ 

๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋กœ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋‹ˆ๊นŒ ์•„์ฃผ์ข‹์€ ์žฅ์ ๋“ค์ด ๋งŽ๋‹ค.

1๏ธโƒฃ Loading, Error States

๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ์˜ useQuery์˜ ๊ธฐ๋ณธ ๋ฆฌํ„ด ๊ฐ’์œผ๋กœ isLoading, isError, isFetching, error ๋“ฑ ๋กœ๋”ฉ๊ณผ ์• ๋Ÿฌ์— ๊ด€๋ จ๋œ ์ƒํƒœ๊ฐ’์„ ๋ฆฌํ„ดํ•œ๋‹ค. ๊ธฐ์กด ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ state๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜์˜€๋Š”๋ฐ, ์ด๋Ÿฐ ๋ถˆํ•„์š”ํ•œ state์‚ฌ์šฉ์„ ์ค„์—ฌ์ค€๋‹ค.

2๏ธโƒฃ Pagination & Infinite scroll

๊ณ ์œ ํ•œ ํ‚ค๊ฐ’์„ ํ†ตํ•˜์—ฌ, ํŽ˜์ด์ง€ ๋„ค์ด์…˜์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฌดํ•œ์Šคํฌ๋กค๋ง๊ณผ ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ hooks์™€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ๊ณตํ•˜์—ฌ, ์ตœ์‹ ์ƒํƒœ์— ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ๋“ค์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

3๏ธโƒฃ Prefetching

ํŽ˜์ด์ง€๋„ค์ด์…˜์˜ ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์งˆ ๊ฒฝ์šฐ ๋“ฑ ๋ฏธ๋ฆฌ ํ”„๋ฆฌํŒจ์นญ์„ ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธฐ๋Š”๋ฐ, ์ด ๋•Œ ํ”„๋ฆฌํŒจ์นญ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋งค์„œ๋“œ๋“ค์ด ์žˆ์–ด ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

// App.js
import { Posts } from "./Posts";
import "./App.css";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
const App=() => {
 return (
  <QueryClientProvider client={queryClient}>
   <div className="App">
    <h1>Blog Posts</h1>
     <Posts />
   </div>
   <ReactQueryDevtools position={"bottom-left"} initialIsOpen={false} />
 </QueryClientProvider>
)
}
// Post.js
//...์ƒ๋žต
async function fetchPosts(pageNumber) {
  const response = await fetch(
   `${process.env.REACT_APP_API_URL}/posts?_limit=${MAX_PAGE}&_page=${pageNumber}`
  );
 return response.json();
}
const queryClient= useQueryClient() //ํ”„๋กœ๋ฐ”์ด๋”์— props์— ๋‹ด๊ธด queryClient์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด๋‹ค.
const [currentPage,setCurrentPage]= useState(1);
useEffect(() => {
  const nextPage= currentPage+1;
    queryClient.prefetchQuery(["posts", nextCount], () =>
     fetchPosts(nextCount)
  );
},[currentPage,queryClient])

์ด๋ ‡๊ฒŒ queryClient.prefetchQuery ๋ฅผ ํ†ตํ•˜์—ฌ, ๋ฐ์ดํ„ฐ๋ฅผ ํ”„๋ฆฌํŒจ์นญ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ 1๋ฒˆ์งธ ํŽ˜์ด์ง€๋„ค์ด์…˜์—์„œ, 2๋ฒˆ์งธ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์™€์ ธ, DevTools์— inactive ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์˜ต์…˜์—๋Š” useQuery๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ์˜ต์…˜๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

4๏ธโƒฃ Mutations

useQuery์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ์— ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ผ์œผํ‚ค๋Š” ๊ฒฝ์šฐ (create, update, delete)์— ์‚ฌ์šฉ๋œ๋‹ค. useMutation ์œผ๋กœ mutation์„ ์ •์˜ํ•˜๊ณ , mutate ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•œ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์€ useQuery์™€ ๋™์ผํ•˜๋‹ค.

useMutation(addTodo, {
// ๋ฎคํ…Œ์ด์…˜ ์‹œ์ž‘
onMutate: (variables) => {
return { id: 1 };
},
//์• ๋Ÿฌ๋‚ฌ์„ ๋•Œ ์ฝœ๋ฐฑํ•จ์ˆ˜
onError: (error, variables, context) => {
console.log(`rolling back optimistic update with id ${context.id}`);
},
//์„ฑ๊ณตํ–ˆ์„ ๋•Œ ์ฝœ๋ฐฑํ•จ์ˆ˜
onSuccess: (data, variables, context) => {
console.log('success')
},
// ์„ฑ๊ณต์ด๋“  ์—๋Ÿฌ๋“  ์–ด์จŒ๋“  ๋๋‚ฌ์„ ๋•Œ
onSettled: (data, error, variables, context) => {
console.log("finish")
},
});

์ด ์ด์™ธ์—๋„ ์š”์ฒญ์„ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜, Mutationํ• ๋•Œ๋‚˜ useQuery๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ์žฌ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ์˜ต์…˜์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์นดํ…Œ๊ณ ๋ฆฌ | TAG :

#react-query