일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- stringreader
- StringTokenizer
- 머신러닝
- 혁신의기술2:신뢰의미래 블록체인을 만나다
- biginteger사용법
- 해시
- 우선순위큐
- national instruments
- 단국대학교 k-mooc
- 자바스크립트
- K-MOOC 단국대학교 홍보단
- 컴파일시스템
- 딥러닝
- 오블완
- 블록체인
- 티스토리챌린지
- Entity
- 시스템프로그래밍
- CSS 기초
- html기초
- 자바문자열구분
- 자바입력받기
- 블록체인 강의
- 자바
- 2차원배열정렬
- K-MOOC
- TypeScript
- Node
- 디스크블록할당
- 블록체인강의
- Today
- Total
열정 실천
[React] 서버 데이터 관리 :: React-Query 사용하기 본문
클라이언트 상태(Client State)란?
- 서버와 독립적인 데이터로, UI 동작이나 사용자 입력에 의해 생성 및 관리다.
- 컴포넌트 간 데이터 공유, 사용자 인터페이스 상태(모달 열림/닫힘, 폼 입력 값 등)에 주로 사용된다.
- React 내장 기능으로는 { useState, useReducer, useContext } 등이 있다.
- 클라이언트 상태 관리 라이브러리는 Redux, Zustand, Recoil 등이 있다.
서버 상태(Server State)란?
- 서버에서 제공된 데이터로, 클라이언트에서 이를 받아 관리한다.
- API를 통해 서버 데이터를 가져오고, 캐싱, 동기화, 에러 처리 등의 작업이 필요하다.
- React 내장 기능으로는 { useEttect, fetch, axios } 등이 있다.
- 서버 상태 관리 라이브러리는 React Query, SWR, Redux Toolkit Query 등이 있다.
React 내장 기능 | 라이브러리 | |
클라이언트 상태 | useState, useReducer, Context | Redux, Zustand, Recoil |
서버 상태 | useEffect, fetch, axios | React Query, SWR, Redux Toolkit Query |
오늘 새로 공부할 React-Query는 서버 상태 관리의 대표 라이브러리이다.
🤔 그래서 React-Query를 왜 쓰는건데?
▶️▶️ 자동 캐싱, 리페칭, 로딩 및 에러 상태 관리 제공한다.
React-Query를 쓰는 이유 1. 캐싱
캐싱(Caching)은 React Query의 핵심 기능 중 하나로, 데이터를 서버에서 가져온 후 로컬에 저장해놓고, 이를 중복 요청 없이 재사용할 수 있게 하는 메커니즘이다. 이러한 캐싱은 애플리케이션의 성능과 효율을 크게 향상시킨다.
▪️쿼리 키를 사용한 캐시 식별 및 저장
const fetchUser = () => axios.get('/api/user');
const { data } = useQuery(['user'], fetchUser); // 'user'가 캐싱 키
위의 코드는 'user'라는 쿼리 키를 기준으로 캐시를 생성하고, 같은 키로 데이터를 재사용한다.
만약 동일한 키를 사용하는 요청을 하면 서버 요청 없이 캐싱된 데이터를 반환한다.
▪️데이터 무효화
캐싱된 데이터가 오래되었거나 변경되었을 가능성이 있는 경우 데이터를 다시 가져와햐하는데
이를 데이터 무효화라고 하며 invalidateQueries를 통해 수동으로 무효화 할 수 있다.
const queryClient = useQueryClient();
const handleUpdateUser = async () => {
await axios.post('/api/update-user', { name: 'John Doe' });
queryClient.invalidateQueries(['user']); // 'user' 키의 캐시를 무효화
};
▪️캐싱 만료 시간 관리
React Query는 데이터를 stale(오래된) 상태와 fresh(신선한) 상태로 구분한다.
기본적으로 데이터는 가져온 직후 fresh 상태이며, 이후 staleTime(기본값: 0ms)이 지나면 stale 상태가 된다.
stale 상태일 때는 캐싱된 데이터를 사용하지만, 필요 시 백그라운드에서 데이터를 새로 가져온다.
const { data } = useQuery(['user'], fetchUser, {
staleTime: 60000, // 60초 동안 데이터를 fresh 상태로 유지
});
▪️캐싱시간 TTL
TTL(cacheTime)은 캐싱된 데이터가 메모리에 유지되는 시간을 결정한다. 기본값은 5분으로, 이 시간이 지나면 캐시가 삭제된다.
const { data } = useQuery(['user'], fetchUser, {
cacheTime: 1000 * 60 * 10, // 10분 동안 캐시 유지
});
React-Query를 쓰는 이유 2. 리페칭
리페칭(Refetching)이란 이미 가져온 데이터를 다시 가져오는 작업을 의미한다.
서버에서 데이터가 변경이 되었거나, 네트워크가 끊겼다가 다시 연결되었거나, 사용자가 새로고침을 했거나 등
데이터의 정확성과 최신성을 유지하기 위해 서버에서 데이터를 다시 요청할 필요가 있다.
자동 리페칭
const { data, isFetching } = useQuery(['posts'], fetchPosts, {
refetchOnWindowFocus: true, // 브라우저 포커싱 시 리페칭
refetchOnReconnect: true, // 네트워크 복구 시 리페칭
refetchInterval: 60000, // 60초마다 데이터 새로고침
});
수동 리페칭
const { data, refetch, isFetching } = useQuery(['user'], fetchUser);
return (
<div>
<button onClick={() => refetch()}>Refresh</button>
{isFetching ? <p>Fetching data...</p> : <p>User: {data.name}</p>}
</div>
);
이렇게 수동, 자동 두 가지 방법으로 리페칭이 호출되면
React- Query는 기존 데이터를 캐싱하고, 새 데이터를 요청한 후 UI를 업데이트한다.
React-Query를 쓰는 이유 3. 로딩 및 에러 상태 관리
데이터 페칭 과정에서 발생하는 로딩 상태와 에러 상태를 간단하게 관리할 수 있게 하여
별도의 로직 없이 데이터의 요청 상태를 UI와 동기화하기 쉽다.
로딩 상태 관련 반환값 | isLoading | 쿼리가 처음 실행되고 데이터를 가져오는 동안 true * 첫 번째 로드에만 적용 |
isFetching | 데이터를 가져오는 동안 항상 true / 리페칭 중에도 true | |
에러 상태 관련 반환값 | isError | 데이터 페칭 중 에러가 발생한 경우 true |
error | 발생한 에러 객체를 반환 |
이러한 상태 반환값은 useQuery를 사용할 때 데이터를 가져오는 것처럼 받아올 수 있다.
const { data, isError } = useQuery(['user'], fetchUser, {
retry: 3, // 3번까지 재시도
retryDelay: 2000, // 재시도 간격 2초
});
이외에도 useQuery가 반환하는 데이터는 여러가지이다.
React Query의 useQuery가 반환하는 데이터의 종류
{
data, // 서버에서 가져온 데이터
error, // 에러 객체
isLoading, // 로딩 중 여부
isFetching, // 백그라운드 리페칭 여부
isError, // 에러 발생 여부
isSuccess, // 성공 여부
status, // 현재 상태 ('idle', 'loading', 'error', 'success')
isStale, // 데이터가 오래되었는지 여부
dataUpdatedAt, // 데이터 마지막 업데이트 시간
errorUpdatedAt, // 에러 마지막 발생 시간
refetch, // 데이터를 다시 가져오는 함수
remove, // 캐싱된 데이터 제거 함수
fetchStatus, // 현재 페칭 상태 ('fetching', 'paused', 'idle')
isPaused, // 쿼리가 일시 중지되었는지 여부
}
👇 기존 코드에 React-Query를 적용해보자!! 👇
1. 기존 코드 (useState, useEffect, Axios 사용)
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const MyPage = () => {
const [babyName, setBabyName] = useState('아기이름'); //아기 이름
const [birthDate, setBirthDate] = useState('2000-01-01'); //아기 생일
useEffect(() => {
const fetchBabyData = async () => {
try {
const { data: { baby } } = await axios.get('/users/me'); //서버에서 데이터 가져오기
setBabyName(baby?.babyName || '아기이름');
setBirthDate(baby?.birthDate || '2000-01-01');
} catch (error) {
console.error('Error fetching baby data:', error);
}
};
fetchBabyData();
}, []);
return (
<div>
<h1>아기 정보</h1>
<p>이름: {babyName}</p>
<p>생일: {birthDate}</p>
</div>
)
}
지금까지는 useState를 사용하여 가져올 데이터 변수를 선언한 뒤, axios로 데이터를 불러와 setState 호출을 통해 응답 당시의 server state를 wrapping 하였다.
1. 수정한 코드 (Axios, React-Query 사용)
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
// 서버 데이터 가져오는 함수
const fetchBabyData = async () => {
const { data } = await axios.get('/users/me');
return data.baby;
};
const MyPage = () => {
// React Query를 사용해 데이터 페칭
const { data: baby, isLoading, error } = useQuery(['babyData'], fetchBabyData, {
initialData: {
babyName: '아기이름',
birthDate: '2000-01-01',
}, // 초기값 설정
});
// 로딩 상태 처리
if (isLoading) return <div>Loading...</div>;
// 에러 처리
if (error instanceof Error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>아기 정보</h1>
<p>이름: {baby.babyName}</p>
<p>생일: {baby.birthDate}</p>
</div>
);
};
export default MyPage;
수정한 코드는 axios를 통해 데이터를 가져오는 함수를 이용하여 useQuery는 'babyData'라는 쿼리키로 데이터를 가져온다.
데이터가 로드 중(isLoading)이면 "Loading..." 메시지를 표시하고 서버 요청 중 오류(error)가 발생하면 에러 메시지를 표시한다.
'개발 공부 > React' 카테고리의 다른 글
[React] 백엔드 없이 빠른 API 구현 :: Json-Server 사용법 (0) | 2025.01.04 |
---|---|
[React] useState 사용법 (+ 배열 or 객체 state 값 변경) (0) | 2023.07.28 |
[React] useEffect 사용법 - mount, unmount, update (0) | 2023.07.27 |
[React] 리액트의 꽃, 컴포넌트 - 함수형 컴포넌트, import&export (0) | 2023.07.27 |