혜심 블로그

프론트엔드

useQuery vs getQueryData: 언제 무엇을 사용해야 할까?

혜심
9 조회

오늘은 React Query를 사용할 때 자주 고민하게 되는 주제에 대해 이야기해보려고 합니다. 바로 useQuerygetQueryData의 사용에 관한 것인데요. 이 두 가지 방법 중 어떤 것을 선택해야 할지, 그 기준에 대해 알아보겠습니다.


React Query는 비동기 데이터 관리를 쉽게 해주는 강력한 도구입니다. 하지만 useQuerygetQueryData 사이에서 어떤 것을 선택해야 할지 고민하는 경우가 많습니다. 이 포스팅에서는 이 두 가지의 차이점을 명확히 하고, 각각의 사용 시점에 대한 가이드를 제공하고자 합니다.

1. useQuery: 컴포넌트 내 데이터 fetching의 표준

useQuery는 React Query의 핵심 기능을 제공하는 훅으로, 컴포넌트 내에서 데이터를 fetching하고 상태를 관리할 때 가장 일반적으로 사용됩니다. 주요 특징은 다음과 같습니다:

  • 데이터 캐싱: 데이터가 캐싱되어 같은 데이터를 다시 요청할 때 네트워크 요청을 줄입니다.
  • 자동 에러 처리: 네트워크 오류 발생 시 자동으로 에러 상태를 관리합니다.
  • 로딩 상태 관리: 데이터 로딩 중일 때 로딩 상태를 자동으로 제공합니다.
  • 데이터 자동 갱신: 데이터가 변경될 때마다 자동으로 갱신합니다.

아래는 useQuery를 사용하는 예제입니다:

import { useQuery } from 'react-query'; interface Todo { id: number; title: string; completed: boolean; } const fetchTodos = async (): Promise<Todo[]> => { const response = await fetch('<https://api.example.com/todos>'); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }; const TodoList: React.FC = () => { const { data, isLoading, error } = useQuery<Todo[], Error>('todos', fetchTodos); if (isLoading) return <div>Loading...</div>; if (error) return <div>An error occurred: {error.message}</div>; return ( <ul> {data?.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ); };

언제 useQuery를 사용해야 할까?

컴포넌트가 데이터를 직접 관리하고 그 상태를 추적해야 하는 경우, useQuery를 사용하는 것이 가장 적합합니다. 예를 들어, 컴포넌트가 렌더링될 때마다 데이터를 가져와야 하거나, 데이터 로딩 상태와 에러 처리를 함께 관리해야 할 때입니다. useQuery는 이러한 상황에서 컴포넌트의 복잡성을 줄이고, 상태 관리의 일관성을 유지할 수 있습니다.

2. getQueryData: 컴포넌트 외부에서의 데이터 접근

getQueryData는 React Query의 캐시에서 이미 가져온 데이터를 직접 접근할 때 사용하는 유틸리티 함수입니다. getQueryData는 서버와의 동기화 상태를 보장하지 않기 때문에, 데이터의 최신성보다 캐시된 데이터의 사용이 중요한 경우에만 사용하는 것이 좋습니다.

사용 예제

import { useQueryClient } from 'react-query'; const SomeComponent: React.FC = () => { const queryClient = useQueryClient(); const handleButtonClick = () => { const todoData = queryClient.getQueryData<Todo[]>('todos'); if (todoData) { console.log('Current todos:', todoData); } }; return <button onClick={handleButtonClick}>Log Todos</button>; };

언제 getQueryData를 사용해야 할까?

getQueryData는 다음과 같은 상황에서 유용합니다:

  • 서버 사이드 렌더링(SSR): 서버에서 데이터를 미리 가져온 후, 클라이언트 측에서 동일한 데이터를 재사용할 때.
  • 이벤트 핸들러 내에서의 데이터 접근: 이미 가져온 데이터를 빠르게 접근해야 할 때.
  • 비동기 함수에서의 데이터 사용: 다른 비동기 로직에서 최신 상태를 신경 쓰지 않고 캐시된 데이터를 활용할 때.

그러나, 데이터가 최신인지 확인해야 하거나 동기화된 상태가 중요한 경우에는 useQuery를 사용하여 데이터를 다시 가져오는 것이 더 안전합니다.

3. 부모-자식 관계에서의 데이터 전달

React의 단방향 데이터 흐름 원칙에 따라, 부모 컴포넌트에서 데이터를 가져온 후 자식 컴포넌트에 props로 전달하는 것이 일반적입니다. 이 방법은 컴포넌트 간의 데이터 흐름을 명확하게 유지하며, 데이터 관리의 일관성을 유지하는 데 도움이 됩니다.

사용 예제

interface TodoListProps { todos: Todo[]; } const ParentComponent: React.FC = () => { const { data } = useQuery<Todo[], Error>('todos', fetchTodos); return <TodoList todos={data || []} />; }; const TodoList: React.FC<TodoListProps> = ({ todos }) => { return ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ); };

언제 이 방식을 선택해야 할까?

부모 컴포넌트가 여러 자식 컴포넌트에 동일한 데이터를 전달해야 하거나, 데이터를 하나의 소스로부터 관리해야 할 때 유용합니다. 하지만 자식 컴포넌트가 독립적으로 데이터를 관리해야 하는 상황에서는 자식 컴포넌트에서 useQuery를 사용하여 데이터 fetching을 직접 관리하는 것도 고려할 수 있습니다.

4. 성능 최적화와 일관성 유지

성능을 최적화하기 위해 컴포넌트 내에서 useQuerygetQueryData를 적절히 혼용하는 것도 중요합니다. 예를 들어, getQueryData를 사용해 이미 캐시된 데이터를 빠르게 가져올 수 있는 상황에서는 굳이 useQuery를 사용해 네트워크 요청을 반복할 필요가 없습니다.

const OptimizedComponent: React.FC = () => { const { data: todoData } = useQuery<Todo[], Error>('todos', fetchTodos); return ( <div> {todoData ? `Total todos: ${todoData.length}` : 'Loading...'} </div> ); };

일관성과 성능 사이의 균형 잡기

컴포넌트 내부에서는 useQuery를 사용하여 데이터 fetching과 상태 관리를 일관되게 하는 것이 좋습니다. 그러나 성능상의 이유로, 이미 캐시된 데이터를 사용하는 것이 적절한 상황에서는 getQueryData를 사용하는 것도 고려해야 합니다. 이처럼 상황에 맞는 선택이 필요합니다.

결론

  • useQuery: 컴포넌트 내에서 데이터를 fetching하고 상태를 관리할 때 사용합니다. 컴포넌트의 렌더링과 동기화된 최신 데이터를 필요로 할 때 적합합니다.
  • getQueryData: 컴포넌트 외부에서 이미 캐시된 데이터에 빠르게 접근해야 할 때 사용합니다. 그러나 최신성보다는 성능이 중요한 경우에만 사용하는 것이 좋습니다.
  • 부모-자식 관계: 부모 컴포넌트에서 데이터를 fetching한 후, 자식 컴포넌트에 props로 전달하는 것이 일반적이나, 자식 컴포넌트가 독립적으로 데이터를 관리해야 하는 경우는 자식에서 useQuery를 사용하는 것도 고려할 수 있습니다.
  • 일관성 유지와 성능 최적화: 컴포넌트 내에서 일관성을 유지하면서도 성능을 최적화하는 방법을 상황에 맞게 선택해야 합니다.

React Query를 사용할 때, 이 두 가지 방법을 잘 활용하면 코드의 유지보수성과 성능을 모두 챙길 수 있습니다. 상황에 따라 적절한 도구를 선택하는 것이 중요하며, 이를 통해 예측 가능한 데이터 관리 패턴을 구축할 수 있습니다.