React Query ํบ์๋ณด๊ธฐ! ๐
React ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ์ผ์ ๋งค์ผ์ ์๋ช ๊ฐ์ ์ผ์ด์ฃ . ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ , ์บ์ฑํ๊ณ , ๊ฐฑ์ ํ๋ ๊ฒ๋ง์ผ๋ก๋ ๋จธ๋ฆฌ๊ฐ ์ํ ๋๊ฐ ๋ง์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฐ ๋ฐ๋ณต๋๋ ์์ ์ โ๊น๋ํ๊ฒโ ์ฒ๋ฆฌํด์ฃผ๋ ์น๊ตฌ๊ฐ ์์ต๋๋ค. ๋ฐ๋ก React Query! ๐
React Query๋ ํด๋ผ์ด์ธํธ ์ํ์ ์๋ฒ ์ํ๋ฅผ ๊น๋ํ๊ฒ ๊ด๋ฆฌํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ API ํต์ ์ ๋ณต์ก์ฑ์ ํฌ๊ฒ ์ค์ฌ์ค๋๋ค. ์ค๋์ React Query์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๊ณผ ํ์ฉ ๋ฐฉ๋ฒ์ ๋ฑ๋ฑ์ด ํํค์ณ ๋ณผ๊ฒ์.
๐ React Query๋?
React Query๋ ์๋ฒ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํฉ๋๋ค:
- ๋ฐ์ดํฐ fetching: ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์บ์ฑํฉ๋๋ค.
- ์๋ ๊ฐฑ์ : ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์๋ก๊ณ ์นจํฉ๋๋ค.
- ์ค๋ฅ ๊ด๋ฆฌ: ์์ฒญ์ด ์คํจํ์ ๋ ์ฌ์๋ ๋ก์ง์ ์ ๊ณตํฉ๋๋ค.
- ์บ์ฑ: ๋์ผํ ์์ฒญ์ ๋ํด ์บ์๋ฅผ ์ ๊ณตํด ๋คํธ์ํฌ ๋ถ๋ด์ ์ค์ ๋๋ค.
- ์ํ ๊ด๋ฆฌ ํตํฉ: ๋ก๋ฉ ์ํ, ์ฑ๊ณต ์ฌ๋ถ, ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๊ฐ๋จํ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
React Query๋ฅผ ์ฌ์ฉํ๋ฉด, โ๋ฐ์ดํฐ ๋ก๋ฉ -> ๋ก๋ฉ ์ํ ๊ด๋ฆฌ -> ์ฑ๊ณต ๋ฐ ์คํจ ์ฒ๋ฆฌโ๋ผ๋ ์ ํ์ ์ธ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ ๊ฐ๋จํ๊ณ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
๐ React Query์ ์ฃผ์ ํน์ง
1. ์๋ ์บ์ฑ
React Query๋ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ๋ ์๋์ผ๋ก ์บ์ํฉ๋๋ค. ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์์ฒญํ๋ฉด ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋คํธ์ํฌ ์์ฒญ์ ์ต์ํํ ์ ์์ต๋๋ค.
2. ์๋ ๋ฆฌํ์น(Auto Refetch)
๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์์ ๋(ํญ ํฌ์ปค์ค, ๋คํธ์ํฌ ์ฌ์ฐ๊ฒฐ ๋ฑ), React Query๋ ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์๋ก๊ณ ์นจํฉ๋๋ค.
3. ์ฟผ๋ฆฌ ์ฌ์๋
๋คํธ์ํฌ ์์ฒญ์ด ์คํจํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก 3๋ฒ ์ฌ์๋ํ๋ฉฐ, ์ฌ์๋ ๊ฐ๊ฒฉ๋ ์ค์ ํ ์ ์์ต๋๋ค.
4. ์๋ฒ ์ํ ๊ด๋ฆฌ
React Query๋ ์๋ฒ ์ํ์ ํด๋ผ์ด์ธํธ ์ํ๋ฅผ ๋ช ํํ ๊ตฌ๋ถํ์ฌ ๊ด๋ฆฌํฉ๋๋ค. Redux๋ MobX ๊ฐ์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ฝ๊ฒ ํตํฉํ ์ ์์ต๋๋ค.
โฒ๏ธ ์ค์น ๋ฐฉ๋ฒ
React Query๋ฅผ ์ค์นํ๋ ค๋ฉด ์๋ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ธ์:
npm install @tanstack/react-query
npm install @tanstack/react-query-devtools
React Query์ ๊ฐ๋ฐ ๋๊ตฌ๋ ํจ๊ป ์ค์นํ๋ฉด ๋๋ฒ๊น ์ด ํจ์ฌ ํธ๋ฆฌํด์ง๋๋ค. DevTools๋ฅผ ํตํด ์ฟผ๋ฆฌ ์ํ๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ์ ์์ด์.
๐ธ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
1. React Query ํด๋ผ์ด์ธํธ ์ค์
๋จผ์ , ์ ํ๋ฆฌ์ผ์ด์ ์ต์์์ QueryClientProvider๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<MyComponent />
</QueryClientProvider>
);
}
export default App;
2. ๋ฐ์ดํฐ fetching ์์
useQuery ํ ์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๋ก๋ฉ ์ํ์ ์ค๋ฅ๋ฅผ ๊ฐ๋จํ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
import { useQuery } from "@tanstack/react-query";
function MyComponent() {
const { data, isLoading, isError } = useQuery(["todos"], fetchTodos);
if (isLoading) return <p>Loading...</p>;
if (isError) return <p>Error occurred!</p>;
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
async function fetchTodos() {
const response = await fetch("https://jsonplaceholder.typicode.com/todos");
if (!response.ok) throw new Error("Network response was not ok");
return response.json();
}
๐๐ปโโ๏ธ React Query์ ์ํ์ ๋ผ์ดํ์ฌ์ดํด
React Query๋ ๋ฐ์ดํฐ์ ์ํ๋ฅผ ํฌ๊ฒ 3๊ฐ์ง๋ก ๊ตฌ๋ถํฉ๋๋ค:
- isLoading: ๋ฐ์ดํฐ๋ฅผ ์ฒ์ ๊ฐ์ ธ์ค๋ ์ํ.
- isError: ์์ฒญ์ด ์คํจํ ์ํ.
- isSuccess: ๋ฐ์ดํฐ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์์ง ์ํ.
์ด ์ธ์๋ isFetching(๋ฐฑ๊ทธ๋ผ์ด๋ ๋ฐ์ดํฐ ๊ฐฑ์ ), isIdle(์ฟผ๋ฆฌ๊ฐ ์คํ๋์ง ์์ ์ํ) ๋ฑ์ ์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
๐ง๐ปโโ๏ธ React Query์ ๊ณ ๊ธ ๊ธฐ๋ฅ
1. ์ฟผ๋ฆฌ ๋ฌดํจํ(Query Invalidations)
๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํ ํ ๊ธฐ์กด ์ฟผ๋ฆฌ๋ฅผ ๋ฌดํจํํ์ฌ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
import { useMutation, useQueryClient } from "@tanstack/react-query";
function AddTodo() {
const queryClient = useQueryClient();
const mutation = useMutation(addTodo, {
onSuccess: () => {
queryClient.invalidateQueries(["todos"]); // todos ์ฟผ๋ฆฌ ๋ฌดํจํ
},
});
return (
<button onClick={() => mutation.mutate({ title: "New Todo" })}>
Add Todo
</button>
);
}
2. Optimistic Update
์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ ๋น ๋ฅด๊ฒ ๋ฐ์ํ๋๋ก ๋ง๋ค์ด์ค๋๋ค.
const mutation = useMutation(addTodo, {
onMutate: async (newTodo) => {
await queryClient.cancelQueries(["todos"]);
const previousTodos = queryClient.getQueryData(["todos"]);
queryClient.setQueryData(["todos"], (old) => [...old, newTodo]);
return { previousTodos };
},
onError: (err, newTodo, context) => {
queryClient.setQueryData(["todos"], context.previousTodos);
},
onSettled: () => {
queryClient.invalidateQueries(["todos"]);
},
});
3. React Query DevTools
๊ฐ๋ฐ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฟผ๋ฆฌ์ ์ํ์ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>;
โ ๏ธ React Query๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํ ์
1. ์บ์ ์๊ฐ๊ณผ ๊ฐฑ์ ์ ๋ต์ ์ ์ ํ ์ค์
์บ์๊ฐ ์ค๋ ์ ์ง๋๋ฉด ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ค ์ ์๊ณ , ๋๋ฌด ์์ฃผ ๊ฐฑ์ ํ๋ฉด ๋คํธ์ํฌ ๋น์ฉ์ด ์ฆ๊ฐํ ์ ์์ต๋๋ค.
2. ๋ฐ์ดํฐ์ ์์กด์ฑ ๊ด๋ฆฌ
์ฟผ๋ฆฌ ํค๋ฅผ ๋ช ํํ ์ค์ ํ์ฌ, ์๋ํ์ง ์์ ๋ฐ์ดํฐ ๊ฐฑ์ ์ ๋ฐฉ์งํ์ธ์.
3. ๋ฐฑ์๋์ ํ๋ ฅ ํ์
React Query๋ ํด๋ผ์ด์ธํธ ์ธก ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ฏ๋ก, ํจ์จ์ ์ธ API ์ค๊ณ๊ฐ ํจ๊ป ํ์ํฉ๋๋ค.
๐ ๊ฒฐ๋ก
React Query๋ ๋ณต์กํ ์๋ฒ ์ํ ๊ด๋ฆฌ๋ฅผ ๊ฐ๋จํ๊ฒ ๋ง๋ค์ด์ฃผ๋ ํ๋ฅญํ ๋๊ตฌ์ ๋๋ค.
๋ฐ์ดํฐ fetching, ์บ์ฑ, ๊ฐฑ์ ๊น์ง ํ ๋ฒ์ ์ฒ๋ฆฌํ๋, ์ฌ๋ฌ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ ํจ์จ์ ์ผ๋ก ๋์ํ๊ฒ ๋ ๊ฑฐ์์. ์ฒ์์ ์กฐ๊ธ ๋ฏ์ค ์ ์์ง๋ง, ํ ๋ฒ ์ต์ํด์ง๋ฉด ๋์๊ฐ๊ธฐ ํ๋ค ๊ฑฐ๋๋๋ค. ๐
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท