React Query를 사용하여 API 호출과 비동기 데이터를 관리했음.
서버 상태 관리를 위한 라이브러리로, 데이터 페칭, 캐싱, 동기화, 업데이트 등을 쉽게 처리할 수 있게 해준다.
API 호출을 후 데이터 캐싱, 자동 리페칭, 로딩/에러 상태 관리 등을 자동으로 해준다.
useState, useEffect 없이도 데이터 가져오기 가능
핵심 기능
- 데이터 캐싱
- queryKey를 기준으로 데이터를 자동 캐싱하여 불필요한 API 호출 방지. 새로고침 해도 데이터를 유지할 수 있음
- 자동 리패칭(데이터 동기화)staleTime, refreshInterval 옵션을 사용하여 주기적으로 API 호출 가능
- 백그라운드에서 데이터를 자동 업데이트,
- 데이터 갱신(mutations)
- useMutation을 사용하면 POST, PUT, DELETE 같은 요청도 쉽게 처리 가능
🎯 React Query를 언제 써야 할까?
✅ 서버 데이터를 자주 가져와야 할 때
✅ 데이터 캐싱이 필요할 때
✅ 로딩 상태 & 에러 처리를 간단하게 하고 싶을 때
✅ 데이터가 변경될 때마다 새로고침 없이 자동 업데이트하고 싶을 때
query vs. mutation
- query : 데이터를 가져오는 작업(GET 요청)
- mutation : 데이터를 변경하는 작업(POST, PUT, DELETE 요청)
query status
const {
data, // 쿼리 결과 데이터
isLoading, // 첫 로딩중인지 여부
isError, // 오류 발생 여부
error, // 오류 객체
isFetching, // 백그라운드에서 데이터를 가져오는 중인지 여부
refetch // 수동으로 쿼리를 다시 실행하는 함수
} = useQuery({
queryKey : ['todos'], // 캐싱 키
queryFn : () => axios.get("<https://api.example.com/data>").then((res) => res.data),
})
react Query 기본설정
🚀 QueryClientProvider란?
react Query를 사용할 때, 전체 애플리케이션에서 React Query의 상태를 관리하는 역할
필요한 이유 (없으면 오류!)
- QueryClientProvider가 없으면 React Query의 전역 상태를 관리할 수 없어서 오류
- React Query는 내부적으로 데이터를 캐싱하고 상태를 관리하는 Query Client를 사용한다.
- 이 Query Client를 앱 전체에서 공유하려면 QueryClientProvider로 감싸야 한다.
- API 요청을 할 때, 데이터를 전역적으로 캐싱 & 관리
- 자동으로 데이터 새로고침(탭 이동 시 최신 데이터 유지)
- React Query 훅(useQuery, useMutation)을 사용하려면 필수..!
const queryClient = new QueryClient(); // QueryClient 인스턴스를 생성
<QueryClientProvider client={queryClient}> // 전역적으로 상태 관리 가능
</QueryClientProvider>
// queryClient 가 제공하는 주요 기능
const queryClient = new QueryClient({
defaultOptions: {
queries : {
staleTime : 1000 * 60 * 5 // 5분 동안 캐싱 유지(5분동안 데이터 유지, 새로운 요청 방지)
}
}
})
🚀 정리
QueryClientProvider 역할
QueryClient | React Query의 전역 상태 관리 객체 |
QueryClientProvider | 전체 애플리케이션에서 QueryClient를 사용할 수 있도록 함 |
useQuery, useMutation | API 요청을 간편하게 하고, 상태를 자동 관리 |
✔ QueryClientProvider를 사용해야 React Query 기능(useQuery, useMutation)을 정상적으로 사용할 수 있음
✔ 자동 캐싱, 리패칭, 최적화 기능 제공! 🚀
useQuery Hook
useQuery는 React Query에서 데이터를 가져오는 훅.
fetch, axios등을 직접 쓰지 않고도 자동으로 데이터 가져오기 + 캐싱 + 로딩/에러상태 관리
useQuery 주요 옵션
- queryKey : 쿼리를 식별하는 고유 키
- queryFn : 데이터를 가져오는 비동기 함수
- staleTime : 데이터가 ‘fresh’하다고 간주되는 시간
- retry : 실패 시 재시도 여부
- refetchOnWindowFocus : 창으로 다시 돌아오면 자동으로 데이터 새로 고침 (boolean)
refetchOnWindowFocus: false, // 윈도우 포커스 시 자동 리페치 비활성화
- enabled : !!userID // userID가 있을 때만 실행
function Example() {
// 1. useQuery 사용
const { data, isLoading, error } = useQuery({
queryKey: ["exampleData"], // 데이터 캐싱을 위한 키 queryKey : ["posts", 1] posts는 카테고리 이름, 1은 ID 값 // 동일한 쿼리 키가 있으면 자동으로 캐싱하여 중복 API 요청 방지
queryFn: () => axios.get("<https://jsonplaceholder.typicode.com/posts/1>").then((res) => res.data), // API를 호출하고 데이터를 반환하는 역할
});
// 2. 로딩 상태 처리
if (isLoading) return
Loading...
;
// 3. 에러 상태 처리
if (error) return
Error occurred
;
// 4. 성공 시 데이터 표시
return
;
}
useMutation Hook
useMutation은 React Query에서 데이터를 변경(POST, PUT, DELETE 등)할 때 사용하는 훅이에요. 우리 챗토리 앱에서는 챗봇의 응답을 가져오고, 대화 내역을 저장하는데 사용했다.
export const useChatQuery = () => {
const addMessage = useChatStore((state: any) => state.addMessage);
const setIsBotTyping = useChatStore((state: any) => state.setIsBotTyping);
return useMutation({
mutationFn: fetchChatbotResponse, // API 호출 함수
onMutate: () => {
// mutation 시작 전 실행
setIsBotTyping(true); // 입력중 상태로 변경
},
// 성공시 실행
onSuccess: (data) => {
addMessage("assistant", data);
setIsBotTyping(false);
},
// 실패시 실행
onError: (error) => {
console.error("챗봇 응답 실패:", error);
setIsBotTyping(false);
},
});
};
// 사용
chatMutation.mutate([{role:"user", content: input}]];
useMutation 주요 옵션
- mutationFn : 실행할 비동기 함수
- onMutate: 뮤테이션 시작 전 실행할 함수
- onSuccess : 성공 시 실행할 함수
- onError : 실패 시 실행할 함수
🚀 useMutation vs useQuery
기능 useQuery useMutation
사용 목적 | 데이터를 가져올 때 (GET) | 데이터를 변경할 때 (POST, PUT, DELETE) |
자동 실행 여부 | 컴포넌트 마운트 시 자동 실행 | mutate()를 호출해야 실행됨 |
캐싱 | 자동으로 데이터 캐싱 | 직접 invalidateQueries를 호출해야 갱신됨 |
로딩 상태 | isLoading | isPending |
에러 상태 | error | error |
🔄 useQuery와 함께 사용 (데이터 갱신)
데이터를 추가/수정/삭제한 후, 자동으로 화면을 갱신하고 싶다면?
👉 queryClient.invalidateQueries(["queryKey"])를 사용하면 돼요! 🚀
tsx
복사편집
import { useMutation, useQueryClient } from "@tanstack/react-query";
import axios from "axios";
function AddPost() {
const queryClient = useQueryClient(); // ✅ QueryClient 가져오기
const mutation = useMutation({
mutationFn: (newPost) => axios.post("/api/posts", newPost),
onSuccess: () => {
queryClient.invalidateQueries(["posts"]); // ✅ posts 데이터를 새로고침
},
});
return (
<button onClick={() => mutation.mutate({ title: "새 게시글" })}>
게시글 추가
</button>
);
}
✔ queryClient.invalidateQueries(["posts"])를 호출하면
✔ "posts" 데이터를 다시 불러와서 자동으로 최신 상태 유지! 🚀
'한번쯤 들어본 FE 기술' 카테고리의 다른 글
State Hooks (0) | 2025.03.12 |
---|---|
[typescript] type 과 interface (0) | 2025.03.12 |
성능 최적화 (0) | 2025.03.12 |
HTML link 태그의 rel 속성, preconnect, preload, prefetch (0) | 2025.02.12 |
웹 성능을 최적화 하는 여러가지 방법 (1) | 2024.09.23 |