개발 공부 💻/React.js
React-Query 알아보기
고짬이
2022. 12. 22. 09:24
State
- client에서 자체적으로 만드는 state
- server에서 전달 받은 값으로 만드는 state
기존 상태관리
- Redux, Mobx, Recoil 등
클라이언트 쪽 데이터 관리에는 적합할 수 있으나, 서버 쪽 데이터 관리에는 적합하지 않은 점들 존재
React-Query
- 데이터 Fetching, 캐싱, 동기화, 서버 쪽 데이터 업데이트 등을 쉽게 만들어주는 React 라이브러리

장점
- 캐싱
- get 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행
- 데이터가 오래 되었다고 판단되면 다시 get (invalidateQueries)
- 동일 데이터 여러 번 요청하면 한 번만 요청. (옵션에 따라 중복 호출 허용 시간 조절 가능)
- 무한 스크롤 (Infinite Queries)
- 비동기 과정을 선언적으로 관리 할 수 있음
- React Hook과 사용하는 구조가 비슷
캐시
React-Query는 데이터의 캐시 처리를 간편하게 할 수 있는 인터페이스를 제공
- 몇 초 이후에는 데이터가 유효하지 않은 것으로 간주하고 데이터를 다시 불러옴
- 데이터에 변경점이 있는 경우에만 리렌더링을 유발
- 유저가 탭을 이동했다가 다시 돌아왔을 때 데이터를 다시 불러옴
- 데이터를 다시 호출할 때 응답이 오기 전까지는 이전 데이터를 계속 보여줌
필요에 따라서는 로딩바와 같은 대안 UI를 보여주기 위해 loading state를 기본적으로 제공
React-Query는 기본적으로 데이터를 fetching 해온 후 데이터를 캐싱 하게 되며,
해당 데이터가 stale 하다고 판단될 때 데이터를 refetching 해오게 됩니다.
사용하기
https://eunzi-kim.github.io/react-query-app/
0. 설치
npm install react-query 혹은 yarn add react-query
- React의 가장 기본이 되는 곳에 react-query 세팅
// src/index.js
...
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
- 예시 코드
import "./App.css";
import { useQuery } from "react-query";
import axios from "axios";
function App() {
const fetchPci = () => {
return axios.get("https://api.bithumb.com/public/ticker/PCI_KRW");
};
// 첫번째 파라미터로 unique Key, 두번째 파라미터로 비동기 함수
// 여러개의 비동기 query가 있다면 useQueries 사용 좋음
const { isLoading, isError, data, error } = useQuery("pci", fetchPci, {
retry: 0, // 실패시 재호출 횟수
onSuccess: (res) => {
// 성공시 호출
console.log(res.data.data);
},
onError: (e) => {
console.log(e.message);
},
});
if (isLoading) {
return <span>Loading...</span>;
}
if (isError) {
return <span>Error: {error.message}</span>;
}
return (
<div>
<h1>페이코인</h1>
<h2>현재가 : {data.data.data["closing_price"]}</h2>
<h4>
거래금액 :{" "}
{parseInt(data.data.data["acc_trade_value_24H"]).toLocaleString()}원
</h4>
<h4>
거래량: {parseInt(data.data.data["units_traded_24H"]).toLocaleString()}
PCI
</h4>
<p>
{new Date((data.data.data["date"] * 10) / 10 + 3240 * 10000)
.toISOString()
.replace("T", " ")
.replace(/\..*/, "")}
</p>
</div>
);
}
export default App;
- get => useQuery
- post, update => useMutation