⚙️ HTTP 요청을 전송하고 프론트엔드를 백엔드 데이터와 동기화된 상태로 유지하는데 이용하는 라이브러리
캐싱이란 데이터의 복사본을 저장하여 동일한 데이터의 접근 속도를 높이는 방법
기존의 React 기존의 상태관리 코드보다 코드의 양이 적고 구조가 단순하여 유지보수하기 쉬움
React Query에서 제공하는 Caching, Window Focusing Refetching 등 다양한 기능을 이용하여 API 요청과 관련한 핵심 로직에 집중할 수 있음
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
);
}
HTTP요청을 전송하여 데이터를 불러오는 GET과 같이 서버에 저장되어있는 "상태"를 불러와 사용할때 사용한다.
useQuery()
는 비동기로 작동한다.
한 컴포넌트에 다수의 useQuery
가 존재하면 하나씩 실행되는것이 아닌, 다수가 동시에 실행된다.
import { fetchEvents } from "../../util/http.js";
const { data, isPending, isError, error } = useQuery({
queryKey: ["events"], // "events를 Unique Key로 사용
queryFn: fetchEvents,
options,
});
export async const fetchEvents = () => {
const response = await fetch("http://localhost:3000/events");
if (!response.ok) {
const error = new Error("An error occurred while fetching the events");
error.code = response.status;
error.info = await response.json();
throw error;
}
const { events } = await response.json();
return events;
}
useQuery
마다 부여되는 고유한 Key 값, useQuery
는 Hook 요청마다 고유한 Unique Key 를 필요로 한다.
React Query v4 부터는 모든 queryKey
는 배열로 선언되어야 한다.
쿼리 키를 이용하여 요청으로 생성된 데이터를 캐시 처리한다.
동일한 요청을 사용하면 이전의 요청의 응답을 재사용할 수 있다.
Promise
처리가 이루어지는 함수로, 서버에 요청을 하는 API 코드가 들어감
React-Query에는 HTTP를 전송하는 로직이 내장되어 있지 않음
요청을 전송하는 코드는 직접 작성해야함
useQuery
가 실행되면 객체가 반환된다.
여기에는 data, isPending, isLoading, isError 등등 여러가지가 있다.
useQuery 공식문서
React Query는 기본적으로 캐싱된 데이터를 stale
한 상태로 여긴다.
stale이란 최신화가 필요한 데이터로 stale
한 상태가 되면 refetch
된다.
staleTime
은 stale -> refetch
에 걸리는 시간이다.
기본값은 0이므로 따로 설정하지않으면 refetch가 무조건 실행된다.
데이터 조회(GET)외 POST,PUT,DELETE 와 같이 데이터 변경 및 삭제 작업을 할때 사용한다. 데이터를 저장하지 않으므로 queryKey는 필요없다.
import { Link, useNavigate } from 'react-router-dom';
import { useMutation } from '@tanstack/react-query';
import Modal from '../UI/Modal.jsx';
import EventForm from './EventForm.jsx';
import { createNewEvent } from '../../util/http.js';
import ErrorBlock from '../UI/ErrorBlock.jsx';
export default function NewEvent() {
const navigate = useNavigate();
const { mutate, isPending, isError, error } = useMutation({
mutationFn: createNewEvent,
});
function handleSubmit(formData) {
mutate({ event: formData });
}
return (
<Modal onClose={() => navigate('../')}>
<EventForm onSubmit={handleSubmit}>
{isPending && 'Submitting...'}
{!isPending && (
<>
<Link to='../' className='button-text'>
Cancel
</Link>
<button type='submit' className='button'>
Create
</button>
</>
)}
</EventForm>
{isError && <ErrorBlock title='이벤트 생성 실패' message={error.info?.message}/>}
</Modal>
);
}
References : https://tech.kakaopay.com/post/react-query-1/