
react-query 를 첫 사용하면서 습득한 지식을 공유합니다.
1) 간편한 데이터 관리
데이터 가져오기, 캐싱, 동기화 및 업데이트 처리를 간편하게 할 수있게 해준다.
2) 실시간 업데이트 및 동기화
실시간 데이터 업데이트와 자동 동기화를 지원하여 서버와 클라이언트 데이터의 일관성 유지를 도와준다.
3) 데이터 캐싱
데이터를 캐싱하여 불필요한 API 요청을 줄이고 애플리케이션의 성능을 향상시킨다.
4) 서버 상태 관리
서버 상태 관리 (예를들면 로딩중, 에러, 성공 등의 상태)를 간편하게 처리 가능하다.
5) 간편한 설정
React Query는 간단한 설정으로 사용 가능하다.
설치하기
npm install @tanstack/react-query @tanstack/react-query-devtools
세팅하기 (QueryClientProvider 로 감싸주기)
최상위 컴포넌트를 QueryClientProvider 로 감싸주면된다. (App.js)
const root = ReactDOM.createRoot(document.getElementById('root'));
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools /> {/* 선택 사항 이거 안넣으면 밑에 그림 안뜸 */}
<App/>
</QueryClientProvider>
);
그러면 아래 예쁜 그림이 뜬다.

간단하게 useQuery 사용해보기
이전 fetch나 axios를 이용한 코드
const [, setData] = useState()
const getNaverPage = async () => {
let response = await axios.get("someurl");
return response.data
};
useEffect(() => {
getNaverPage().then((data) => {
setData(data);
})
}, []);
같은 역할을 하는 react_query 코드
React Query v5부터 useQuery 훅은 하나의 객체 인수를 받는 방식으로 변경되었습니다
import './App.css'
import axios from "axios";
import {useQuery} from "@tanstack/react-query";
function App() {
const getSomeData = async () => {
return await axios.get("someurl");
};
let {
data,
isLoading
} = useQuery({
queryKey: ["some"],
queryFn: getSomeData
});
return (
<div>{isLoading ? "로딩중..." : JSON.stringify(data.data)}</div>
)
}
export default App
위 처럼 작성 하면 평소에 내가 사용하던 isFetching, isLoading 상태들을 리액트 쿼리가 알아서 해준다.


react query 에서 주용 사용되는 기능인 Query와 Mutation을 알아보자
react query에서는 API 요청을 위 두가지 형태로 처리한다.
QueryMutation
query 함수를 이용해 데이터를 가져오고 캐싱할수 있다.
보통 데이터 페칭용으로 사용되고
보통 GET으로 가져오는 코드에서 사용한다.
💡 공식문서에서는 서버에 데이터를 수정하는 코드라면 Mutation을 권장한다!

const { data,isLoading,isFetching,... } = useQuery(
queryKey,
queryFunction,
options,
)
인자 설명
useQuery에 사용되는 옵션을 지정하는 객체이다.isLoading : 데이터를 가져오는 중인지 알려주는 상태 boolean 변수
isFetching : 위와 동일
error : 에러가 발생했을때 반환되는 객체
위 리턴값들 이외에 다양한 리턴값들이 많다 기능이 궁금하다면 공식문서를 확인하자
보통 데이터를 업데이트하고 캐시를 업데이트 할 사용한다.
보통 데이터 생성, 수정, 삭제 용으로 사용되며 POST, PUT, DELETE 요청시에 사용합니다.
아래는 서버에 새 할일 (todo)를 생성하는 예제 코드이다.
const getSomeData = async (newTodo) => {
return await axios.post("http://127.0.0.1:3000", {할일: newTodo});
};
let {mutate, data, isPending, isIdle} = useMutation({
mutationFn: getSomeData,
onSuccess: (data, variables, context) => {},
onMutate: (variables) => {}
})
const [input, setInput] = useState("")
return (
<>
<input type="text" onChange={(e) => {
setInput(e.target.value)
}} value={input}/>
<button onClick={() => {
mutate(input);
}}>보내기
</button>
{!isIdle && <div>{isPending ? "보내는중..." : JSON.stringify(data.data)}</div>}
</>
)
mutation 은 자동으로 실행되지 않기 때문에 click이나 submit 으로 호출해줘야 한다.
useMutation 안 옵션들
onMutate
mutate 가 발생하기 전 실행되는 함수!
인자값 : variables 는 mutationFn 에 전해진 변수이다.
반환값: 컨텍스트(context) 객체를 반환하여 나중에 onError, onSuccess, onSettled 콜백에서 사용할 수 있다.
onSuccess
mutate 가 성공했을때 실행되는 콜백
인자값 :
datavarialescontextonSettled
mutate가 성공 또는 실패 했을때 실행되는 콜백!
무조건 onSuccess가 먼저 실행되는 특징이 있음!
더 많은 정보는 공식문서 에서…
Mutations | TanStack Query React Docs
staletime, gcTime 옵션을 사용하면 데이터 캐싱 기능을 이용할 수 있다.
갱신 지연 시간으로 신선한 데이터 기준 시간 설정이다
만약 5분으로 설정했다면 처음 가져오고 5분동안은 가져오지 않고 5분이 지나서야 새로운 데이터를 가져온다.
기본적으로 0 으로 설정되어 있어 한번 가져오면 만료되고 계속 다시 가져온다.
// 간단한 버튼을 눌렀다 떼면 ShowData 컴포넌트가 마운트, 언마운트 되는 App.js 파일이다.
<button onClick={() => {
setIsClick(!isClick)
}}>click
</button>
{isClick && <ShowData/>}
//ShowData 컴포넌트
const ShowData = () => {
const getData = async () => {
return await axios.get("http://127.0.0.1:3000")
};
let {data: someData, isFetching, status} = useQuery({
queryKey: ["some"],
queryFn: getData,
staleTime: 1000 * 5,
})
return (
<div>가져온 데이터
: {isFetching && "가져오는중"}{!isFetching && status === "success" && JSON.stringify(someData.data)}</div>
)
};

stale 되자마자 리렌더링시 다시 데이터를 가져오는 모습
cacheTime)gcTime 시간동안 캐시데이터가 사용되지 않았다면 캐시를 삭제 한다
staletime 를 1시간으로 설정한뒤 gcTime 를 1초로 설정한다면 어떻게 될까?ShowData 컴포넌트는 위와 같다.
...
//ShowData 컴포넌트
const ShowData = () => {
const getData = async () => {
return await axios.get("http://127.0.0.1:3000")
};
let {data: someData, isFetching, status} = useQuery({
queryKey: ["some"],
queryFn: getData,
staleTime: 1000 * 60 * 60,
gcTime: 1000
})
return (
<div>가져온 데이터
: {isFetching && "가져오는중"}{!isFetching && status === "success" && JSON.stringify(someData.data)}</div>
)
};

언마운트 된지 1초도 안됬을때는 캐시데이터를 잘 사용하다가 언마운트된지 1초가 넘자 캐시에서 데이터가 사라지는 모습이다.