STUDY/[ React ]

react query

Lim임 2025. 12. 3. 04:41

https://velog.io/@devjooj/React-React-Query-%EC%82%AC%EC%9A%A9-%EC%9D%B4%EC%9C%A0-Queries-%EA%B0%9C%EB%85%90%ED%8E%B8

 

[React] React-Query 사용 이유 & Queries 개념편

React-Query란?

velog.io

 

📌 fetch().then(...) 방식
장점: 단순하고 직관적, 작은 프로젝트에서 빠르게 사용 가능
단점:
로딩 상태(isLoading)와 에러 상태(error)를 직접 관리해야 함
데이터가 바뀌었을 때 다시 가져오는 로직을 직접 작성해야 함
캐싱이 없어서 같은 요청을 여러 번 보내게 됨
윈도우 포커스 변경, 네트워크 재연결 시 자동 갱신 기능 없음

---

📌
 React Query의 장점
자동 상태 관리
isLoading, isError, data 같은 상태를 자동으로 제공
로딩 스피너나 에러 메시지를 쉽게 처리 가능

캐싱(Cache)
동일한 쿼리 키로 요청하면 캐시된 데이터를 즉시 보여주고, 필요할 때만 새로 가져옴
불필요한 네트워크 요청 감소

자동 리패칭(Refetch)
윈도우 포커스가 돌아왔을 때, 네트워크가 다시 연결됐을 때 자동으로 최신 데이터 가져옴

데이터 동기화
여러 컴포넌트에서 같은 데이터를 공유할 때, 한 번만 요청하고 모두가 최신 상태를 사용 가능

옵션 제어
staleTime, cacheTime, refetchInterval 같은 옵션으로 데이터 갱신 주기를 세밀하게 조절 가능

---

📊
 비교 요약
| 구분 | fetch().then(...) | React Query |
|------|------------------|-------------|
| 로딩/에러 관리 | 직접 구현 | 자동 제공 |
| 캐싱 | 없음 | 있음 |
| 자동 갱신 | 없음 | 있음 (윈도우 포커스, 네트워크 재연결 등) |
| 코드 복잡도 | 단순 | 조금 더 구조화 필요 |
| 대규모 프로젝트 | 관리 어려움 | 서버 상태 관리에 최적화 |

---


 결론: 작은 프로젝트에서는 fetch().then(...)만으로 충분하지만, 데이터가 많고 상태 관리가 복잡해지는 규모 있는 프로젝트에서는 React Query가 훨씬 효율적입니다.

 

 

🧩 1. fetch().then(...) 방식

import { useEffect, useState } from 'react';

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    fetch('/api/todos')
      .then(res => {
        if (!res.ok) throw new Error('네트워크 오류');
        return res.json();
      })
      .then(data => {
        setTodos(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err);
        setLoading(false);
      });
  }, []);

  if (loading) return <p>로딩 중...</p>;
  if (error) return <p>에러 발생: {error.message}</p>;

  return (
    <ul>
      {todos.map(todo => <li key={todo.id}>{todo.title}</li>)}
    </ul>
  );
}

 

- 로딩 상태, 에러 상태를 직접 관리해야 함
- 데이터 갱신(리패칭)을 원하면 useEffect를 다시 작성해야 함
- 캐싱 없음 → 같은 요청을 여러 번 보내게 됨

 

🧩 2. React Query useQuery 방식

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

function TodoList() {
  const { data, isLoading, error } = useQuery(
    ['todos'], // 쿼리 키
    async () => {
      const res = await axios.get('/api/todos');
      return res.data;
    }
  );

  if (isLoading) return <p>로딩 중...</p>;
  if (error) return <p>에러 발생!</p>;

  return (
    <ul>
      {data.map(todo => <li key={todo.id}>{todo.title}</li>)}
    </ul>
  );
}

 

로딩/에러 상태 자동 제공 (isLoading, error)
캐싱 지원 → 같은 키로 요청하면 캐시된 데이터 즉시 사용
윈도우 포커스 변경, 네트워크 재연결 시 자동으로 최신 데이터 가져옴
옵션(staleTime, refetchInterval)으로 데이터 갱신 주기 제어 가능

 

 

기본 구조

useQuery는 이런 객체를 반환합니다:

{ data: ..., // 서버에서 가져온 데이터 isLoading: ..., // 로딩 상태 error: ... // 에러 상태 // 기타 여러 상태 값들... }

---

구조 분해 할당 기본

const { data, isLoading } = useQuery(...);

이렇게 쓰면 dataisLoading이라는 변수에 그대로 값이 들어갑니다. ---

별칭(alias) 주는 방식

const { data: booksData, isLoading: isBooksLoading } = useQuery(...);
  • data: booksDatauseQuery가 반환한 객체의 data 속성을 꺼내서 booksData라는 이름의 변수에 담습니다.
  • isLoading: isBooksLoadingisLoading 속성을 꺼내서 isBooksLoading이라는 이름의 변수에 담습니다.

즉, 왼쪽은 원래 객체의 키 이름, 오른쪽은 내가 새로 쓰고 싶은 변수 이름이에요. ---

예시로 확인

const obj = { data: [1,2,3], isLoading: false }; const { data: booksData, isLoading: isBooksLoading } = obj; console.log(booksData); // [1,2,3] console.log(isBooksLoading); // false

---

정리

  • data원래 객체의 키 이름
  • booksData그 값을 담는 새로운 변수 이름
  • 따라서 booksData를 통해 data의 값을 사용하는 게 맞습니다.

 

'STUDY > [ React ]' 카테고리의 다른 글

목 수업  (0) 2025.12.05
모킹서버 토스트 모달  (0) 2025.12.03
도서상세페이지ㅁ(추후)  (0) 2025.11.30
도서목록만들기(추가예정)  (0) 2025.11.28
Component가 뭔가요?  (0) 2025.11.28