이번 새 프로젝트에 합류하게 되면서 말로만 들었던 React Query를 사용하게 되었다. 사실 프로젝트에서 사용하는 것에는 문제가 크게 없었다.
하지만 저번에 손코딩 면접에서 React Query 문제가 나왔을 때, 정확히 답을 적지 못해서 공부를 좀 해야겠다고 생각했다
1. React Query란?
React Query는 서버 상태(예: API에서 불러온 데이터)를 관리하기 위한 라이브러리
useState나 useEffect 없이도 데이터 fetching, 캐싱, 갱신, 에러처리 등을 자동으로 해준다
데이터 수정 후 useEffect로 다시 패칭하는 방식은 상태 중복과 리패칭 조건 관리의 어려움이 있기 때문에, React Query에서는 invalidateQueries를 통해 필요한 캐시만 무효화하고, 이를 자동으로 refetch하게 만드는 방식이 더 효율적이다
2. useQuery 기본 개념
const { data, isLoading, error } = useQuery(['todos'], fetchTodos);
- ['todos']: 이건 Query Key. 나중에 이 이름으로 캐시 관리함. 캐시를 구분하는 "이름표" 같은 것.
- fetchTodos: 실제 데이터를 불러오는 함수.
- data: 가져온 데이터
- isLoading: 로딩 중 여부
- error: 에러 발생 여부
3. useMutation + useQuery 캐시 최적화 예시
예: 게시글 삭제 후 목록 갱신하기
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
const fetchPosts = async () => {
const res = await fetch('/api/posts');
return res.json();
};
const deletePost = async (id) => {
await fetch(`/api/posts/${id}`, {
method: 'DELETE',
});
};
export default function Posts() {
const queryClient = useQueryClient();
// 캐시 조작할 수 있는 도구
// useQuery는 데이터를 가져와서 자동으로 캐싱
// 여기서 ['posts']는 이 데이터의 키 값
// 같은 키로 불러오면 네트워크 없이 캐시만 사용
const { data: posts } = useQuery(['posts'], fetchPosts);
// 목록 불러오기
// useMutation은 POST, DELETE 같은 요청에 사용
// 버튼 클릭으로 삭제 요청할 수 있게 해준다
// mutation.mutate(id)를 호출하면 deletePost(id)가 실행
const mutation = useMutation(deletePost, {
onSuccess: () => {
// 삭제 성공 시, posts 데이터를 refetch
// 게시글을 삭제했으면 목록도 다시 불러와야한다
// invalidateQueries(['posts'])는 React Query에게 전달:
// “이 키로 캐시된 데이터 오래됐어! 다시 불러와줘!”
// 이걸 쓰지 않으면 목록이 그대로. 데이터는 삭제됐지만 UI에 반영이 안 된다
queryClient.invalidateQueries(['posts']);
},
});
return (
<ul>
{posts?.map((post) => (
<li key={post.id}>
{post.title}
<button onClick={() => mutation.mutate(post.id)}>삭제</button>
</li>
))}
</ul>
);
}'[Study] 개발 공부 > [React] 리액트 공부' 카테고리의 다른 글
| React에서 특정 영역만 인쇄하기(react-to-print) (0) | 2025.10.31 |
|---|---|
| [라이브러리] 짧은 고유 ID 생성해주는 nanoid (0) | 2025.06.10 |
| react-loading-skeleton으로 스켈레톤 UI 만들기 (1) | 2025.05.14 |
| [styled-components/React] styled-components: it looks like an unknown prop "X" is being sent through to the DOM... 경고 메시지 해결하기 (0) | 2025.03.27 |
| [Redux] Redux Thunk를 왜 사용해야 할까 (0) | 2025.02.17 |