raw
Frontend

React Query 서버 상태 관리 안할거야?

2025.01.24·6분

React Query 완벽 가이드: 서버 상태 관리의 시작

목차

  1. React Query란?
  2. 설치 및 설정
  3. 기본 사용법
  4. 실제 사용 예시
  5. 성능 최적화 팁
  6. 자주 묻는 질문

1. React Query란?

React Query는 React 애플리케이션에서 서버 상태 관리를 쉽게 할 수 있게 도와주는 라이브러리입니다.

주요 특징

  • 서버 데이터 캐싱
  • 로딩/에러 상태 자동 관리
  • 페이지네이션 및 무한 스크롤 지원
  • 데이터 자동 업데이트
  • TypeScript 지원

2. 설치 및 설정

설치

bash
1npm install @tanstack/react-query
2# or
3yarn add @tanstack/react-query
4기본 설정
5typescriptCopyimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';
ts
1// QueryClient 인스턴스 생성
2const queryClient = new QueryClient();
3
4function App() {
5 return (
6 <QueryClientProvider client={queryClient}>
7 <MainApp />
8 </QueryClientProvider>
9 );
10}

3. 기본 사용법

ts
1useQuery: 데이터 조회
2typescriptCopyfunction UserProfile() {
3 const { data, isLoading, error } = useQuery({
4 queryKey: ['user', userId],
5 queryFn: () => axios.get(`/api/users/${userId}`)
6 });
7
8 if (isLoading) return <div>로딩중...</div>;
9 if (error) return <div>에러 발생!</div>;
10
11 return <div>{data.name}의 프로필</div>;
12}
13useMutation: 데이터 변경
14typescriptCopyfunction CreateUserForm() {
15 const mutation = useMutation({
16 mutationFn: (newUser) => axios.post('/api/users', newUser),
17 onSuccess: () => {
18 alert('사용자가 생성되었습니다!');
19 }
20 });
21
22 const handleSubmit = (data) => {
23 mutation.mutate(data);
24 };
25
26 return <form onSubmit={handleSubmit}>...</form>;
27}

4. 실제 사용 예시

ts
1로그인 기능 구현
2typescriptCopyfunction LoginScreen() {
3 const loginMutation = useMutation({
4 mutationFn: (credentials) => axios.post('/api/login', credentials),
5 onSuccess: (data) => {
6 // 토큰 저장
7 localStorage.setItem('token', data.token);
8 // 메인 페이지로 이동
9 navigate('/main');
10 },
11 onError: (error) => {
12 alert(error.message);
13 }
14 });
15
16 const handleLogin = (e) => {
17 e.preventDefault();
18 loginMutation.mutate({
19 email,
20 password
21 });
22 };
23
24 return (
25 <form onSubmit={handleLogin}>
26 <input type="email" value={email} onChange={e => setEmail(e.target.value)} />
27 <input type="password" value={password} onChange={e => setPassword(e.target.value)} />
28 <button type="submit" disabled={loginMutation.isLoading}>
29 {loginMutation.isLoading ? '로그인 중...' : '로그인'}
30 </button>
31 </form>
32 );
33}
ts
1무한 스크롤 구현
2typescriptCopyfunction InfinitePostList() {
3 const {
4 data,
5 fetchNextPage,
6 hasNextPage,
7 isFetchingNextPage
8 } = useInfiniteQuery({
9 queryKey: ['posts'],
10 queryFn: ({ pageParam = 1 }) =>
11 axios.get(`/api/posts?page=${pageParam}`),
12 getNextPageParam: (lastPage) => lastPage.nextPage
13 });
14
15 return (
16 <div>
17 {data.pages.map((page) => (
18 page.posts.map((post) => (
19 <PostItem key={post.id} post={post} />
20 ))
21 ))}
22
23 <button
24 onClick={() => fetchNextPage()}
25 disabled={!hasNextPage || isFetchingNextPage}
26 >
27 {isFetchingNextPage
28 ? '로딩중...'
29 : hasNextPage
30 ? '더 보기'
31 : '마지막 페이지'}
32 </button>
33 </div>
34 );
35}

5. 성능 최적화 팁

ts
11. 적절한 캐싱 설정
2typescriptCopyconst queryClient = new QueryClient({
3 defaultOptions: {
4 queries: {
5 staleTime: 1000 * 60 * 5, // 5분
6 cacheTime: 1000 * 60 * 30, // 30분
7 },
8 },
9});
102. 선택적 데이터 가져오기
11typescriptCopyconst { data } = useQuery({
12 queryKey: ['user', userId],
13 queryFn: () => fetchUserData(userId),
14 enabled: !!userId, // userId가 있을 때만 실행
15});
163. 낙관적 업데이트 사용
17typescriptCopyconst mutation = useMutation({
18 mutationFn: updateTodo,
19 onMutate: async (newTodo) => {
20 // 이전 쿼리 취소
21 await queryClient.cancelQueries(['todos']);
22
23 // 이전 값 저장
24 const previousTodos = queryClient.getQueryData(['todos']);
25
26 // 낙관적으로 새 값 설정
27 queryClient.setQueryData(['todos'], (old) => [...old, newTodo]);
28
29 // 롤백을 위한 컨텍스트 반환
30 return { previousTodos };
31 },
32 onError: (err, newTodo, context) => {
33 // 에러 시 롤백
34 queryClient.setQueryData(['todos'], context.previousTodos);
35 }
36});

6. 자주 묻는 질문

Q: React Query vs Redux의 차이점은? A: Redux는 클라이언트 상태 관리에 적합하고, React Query는 서버 상태 관리에 특화되어 있습니다. 두 라이브러리는 상호 보완적으로 사용될 수 있습니다. Q: 캐시된 데이터를 수동으로 갱신하려면? A: queryClient.invalidateQueries()를 사용하여 캐시를 무효화하거나, refetch()를 호출하여 데이터를 다시 가져올 수 있습니다. Q: 오프라인 지원이 가능한가요? A: React Query는 기본적으로 오프라인 상황을 고려하여 설계되었습니다. 오프라인 상태에서도 캐시된 데이터를 사용할 수 있으며, 온라인 상태가 되면 자동으로 데이터를 동기화합니다. 마치며 React Query는 서버 상태 관리의 복잡성을 크게 줄여주는 강력한 도구입니다. 기본적인 설정만으로도 많은 기능을 제공하며, 필요에 따라 세밀한 설정도 가능합니다. 이 가이드가 React Query를 시작하는 데 도움이 되었기를 바랍니다. 더 자세한 내용은 공식 문서를 참조해주세요.