리액트 쿼리 vs 기존 방식

Category
스터디노트 React Query
Status
Published
Tags
React Query
Description
Published
Slug

1. 기존 React 코드로 서버 데이터 관리

useStateuseEffect로 직접 비동기 요청을 관리하는 예시
 
예시: 예약 정보를 서버에서 가져와 렌더링하는 코드

기존 방식

import React, { useState, useEffect } from 'react'; const ReservationComponent = ({ reservationId }) => { const [reservation, setReservation] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchReservation = async () => { try { const response = await fetch(`/api/reservations/${reservationId}`); if (!response.ok) throw new Error('Failed to fetch'); const data = await response.json(); setReservation(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; fetchReservation(); }, [reservationId]); if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <div> <h1>Reservation for {reservation.customerName}</h1> <p>Room: {reservation.roomNumber}</p> </div> ); };

문제점

  1. 중복 코드
      • 다른 컴포넌트에서도 비슷한 API 호출을 한다면 매번 같은 구조를 작성해야 함
      • 로딩, 에러, 데이터 상태 등을 수동으로 관리해야 하므로 코드가 중복되고 복잡해짐
  1. 캐싱 없음
      • 동일한 데이터가 필요한 여러 컴포넌트가 있을 때, 각 컴포넌트마다 중복 요청을 하게 됨
  1. 데이터 동기화 어려움
      • 서버에서 데이터가 변경되었을 때, 이를 실시간으로 업데이트하기가 어려움
      • 개발자가 useEffect를 이용해 데이터 갱신 로직을 직접 구현해야 함
  1. 에러 처리 비효율적
      • 각 API 호출마다 try-catchloading 상태를 매번 설정해야 해서 코드가 길어짐

 

2. React Query로 개선된 코드

React Query를 사용하면 비슷한 기능을 훨씬 간결하게 구현할 수 있음

React Query 방식

import { useQuery } from 'react-query'; import axios from 'axios'; const fetchReservation = async (id) => { const { data } = await axios.get(`/api/reservations/${id}`); return data; }; const ReservationComponent = ({ reservationId }) => { const { data, isLoading, error } = useQuery(['reservation', reservationId], () => fetchReservation(reservationId), { staleTime: 1000 * 60 * 5 } // 5분 동안 캐시 유지 ); if (isLoading) return <p>Loading...</p>; if (error) return <p>Error: {error.message}</p>; return ( <div> <h1>Reservation for {data.customerName}</h1> <p>Room: {data.roomNumber}</p> </div> ); };
 
const { data, isLoading, error } = useQuery(['reservation', reservationId],
첫 번째 인자는 쿼리 키로, ['reservation', reservationId] 형태로 배열을 사용하여 쿼리를 고유하게 식별
 
() => fetchReservation(reservationId),
두 번째 인자는 데이터 fetching 함수로, 여기서는 예약 ID를 인자로 받아 fetchReservation(reservationId)를 호출
 

React Query의 장점

1. 코드가 더 간결함

  • 로딩, 에러, 데이터 상태를 자동으로 관리함
  • useQuery 하나로 데이터 요청과 상태 관리를 해결하므로 코드가 짧고 직관적임
    • 기존 코드에서는 useStateuseEffect로 여러 상태를 수동으로 관리해야 했음
    •  

2. 자동 캐싱

  • 동일한 데이터를 다시 요청할 때 캐시된 데이터를 먼저 보여주고, 필요 시 새로 갱신
  • 예를 들어, 예약 목록과 예약 세부 정보 페이지가 같은 데이터를 요청할 경우 중복 호출을 피할 수 있음
 

3. 자동 리페칭 및 동기화

  • 창을 다시 열거나 포커스할 때 데이터를 자동으로 리페칭
  • 서버에서 데이터가 변경되면 자동으로 갱신되므로 실시간 동기화가 쉬워짐
 

4. 에러와 로딩 처리 간소화

  • API 요청에 대한 에러와 로딩 상태를 자동으로 관리
  • 여러 API 호출에서 중복된 try-catch와 상태 관리 코드가 사라짐
 

기존 코드와 React Query 코드 비교

기능
기존 React 코드
React Query 코드
상태 관리
useState와 useEffect를 직접 사용해야 함
useQuery로 자동 관리
캐싱
수동 구현 필요
자동으로 캐싱 관리
리페칭 및 동기화
직접 구현 필요
창 포커스 시 자동 리페칭
코드 간결성
반복적인 상태 코드 작성 필요
훨씬 더 짧고 직관적
에러 및 로딩 처리
여러 try-catch와 로딩 상태 관리 필요
에러, 로딩 상태 자동 관리
성능 최적화
매번 새로 API 호출
캐싱된 데이터 재사용으로 성능 개선

React Query가 특히 유용한 이유

  1. 키오스크와 같은 복잡한 애플리케이션에서 여러 API를 호출할 때 코드 중복을 줄
  1. 중요한 서버 상태의 일관성을 보장합니다. 예를 들어, 예약 상태가 여러 화면에서 변경될 때 동기화를 쉽게 처리할 수 있음
  1. 실시간 리페칭과 캐싱을 통해 네트워크 요청 수를 줄이고, 성능 최적화가 가능함