리액트 쿼리 병렬요청

Category
스터디노트 React Query
Status
Published
Tags
React Query
Description
Published
Slug
React Query는 여러 모듈에서 동시에 여러 비동기 API 요청을 병렬로 처리할 때도 매우 유용.
병렬 요청을 간단하게 관리할 수 있을 뿐만 아니라,
각 요청의 상태(로딩, 에러, 성공)를 독립적으로 추적할 수 있어,
모듈 간 복잡한 상태 관리 문제를 해결하는 데 유용
 

여러 모듈과 API 요청을 병렬로 처리하는 문제점 (기존 방식)

여러 API 요청을 동시에 처리할 때, 기존 React 방식에서는 다음과 같은 문제들이 발생가능
  1. useEffect 중첩 문제
      • 여러 비동기 요청을 독립적으로 관리하기 위해 각 API 호출마다 useEffectuseState를 설정해야 함
  1. 에러 핸들링 어려움
      • 요청마다 별도로 에러 처리를 해야 하므로 코드가 길고 복잡해짐
  1. 비효율적인 리렌더링
      • 여러 상태를 관리하다 보면 불필요한 리렌더링이 자주 발생함
       

React Query로 병렬 API 요청 관리하기

React Query를 사용하면
각 모듈이나 API 호출을 독립적으로 관리하면서도 병렬 요청을 효율적으로 처리할 수 있음
 

여러 API 요청을 병렬로 처리하기

import { useQuery, useQueries } from 'react-query'; import axios from 'axios'; const fetchUser = (id) => axios.get(`/api/user/${id}`).then((res) => res.data); const fetchReservations = () => axios.get('/api/reservations').then((res) => res.data); const Dashboard = () => { const userId = 1; // 병렬로 두 개의 API 요청 처리 const { data: user, isLoading: userLoading, error: userError } = useQuery( ['user', userId], () => fetchUser(userId) ); const { data: reservations, isLoading: reservationsLoading, error: reservationsError } = useQuery( 'reservations', fetchReservations ); if (userLoading || reservationsLoading) return <p>Loading...</p>; if (userError || reservationsError) return <p>Error occurred!</p>; return ( <div> <h1>Welcome, {user.name}</h1> <ul> {reservations.map((res) => ( <li key={res.id}>Room {res.roomNumber}: {res.status}</li> ))} </ul> </div> ); };

코드 분석

  1. 병렬 요청 관리
      • 위 코드에서는 useQuery 두 개를 사용해 유저 정보예약 목록을 동시에 가져옴
      • 각 요청의 로딩 상태와 에러 상태를 독립적으로 관리함
       
  1. 자동 리렌더링 방지
      • React Query는 상태가 바뀌는 경우에만 리렌더링을 트리거함. 각 요청의 상태가 독립적이기 때문에 불필요한 리렌더링을 피할 수 있음
       
  1. 중복 API 요청 방지
      • 같은 데이터를 여러 컴포넌트에서 요청할 때 캐시된 데이터가 우선 제공되므로 성능 최적화가 가능

복잡한 병렬 요청 관리 (useQueries 사용)

복잡한 상황에서는 여러 API 요청을 배열 형태로 관리할 수 있음

useQueries 예제

const Dashboard = ({ userIds }) => { // 여러 유저의 정보를 병렬로 가져오기 const userQueries = useQueries( userIds.map((id) => ({ queryKey: ['user', id], queryFn: () => fetchUser(id), })) ); if (userQueries.some((q) => q.isLoading)) return <p>Loading...</p>; if (userQueries.some((q) => q.error)) return <p>Error occurred!</p>; return ( <div> {userQueries.map((q, index) => ( <div key={index}> <h2>User {q.data.name}</h2> </div> ))} </div> ); };

useQueries 코드 분석

  1. 동적 병렬 요청
      • useQueries를 사용하면 여러 개의 API 요청을 동시에 관리할 수 있습니다.
      • 이 예제에서는 여러 유저의 정보를 동시에 불러와 배열로 관리합니다.
  1. 상태 통합 처리
      • 각 요청의 상태를 독립적으로 관리하면서도, 배열 내의 상태를 조합해 전체 로딩 및 에러 상태를 쉽게 추적할 수 있습니다.
       

React Query로 병렬 요청 이점

  1. 로딩, 에러 관리 단순화
      • 여러 요청의 상태를 각각 관리하면서도 간결한 코드로 처리할 수 있음
       
  1. 캐싱과 성능 최적화
      • 동일한 데이터를 여러 모듈에서 재사용할 경우 자동 캐시를 통해 네트워크 요청을 줄임
       
  1. 비동기 로직 분리
      • 컴포넌트 내부에 비동기 로직이 엉키지 않으므로 코드 가독성이 높아짐
    1. 모듈 간 독립성 유지
        • 각 모듈에서 동일한 데이터를 필요로 할 때 캐시를 활용해 중복 호출을 방지하고 일관성을 유지