What is "React Query"?
React Query는 데이터 Fetching, 캐싱, 동기화, 서버 쪽 데이터 업데이트 등을 쉽게 만들어 주는 React 라이브러리이다.
→ 서버 상태 관리 라이브러리중 하나이다.
(전역)상태 관리 라이브러리
- redux
- middleware
- redux-saga
- redux-thunk(redux-toolkit에 내장)
- redux-observable
- middleware
- recoil
- mobx
- jotai
- zustand
- xstate
서버 상태 관리 라이브러리
- react-query
- swr
- rtk-query(redux-toolkit에 내장)
Why "React Query"?
등장 배경
기존에 Redux, Mobx, Recoil과 같은 다양하고 훌륭한 상태 관리 라이브러리들이 있긴 하지만, 클라이언트 쪽의 데이터들을 관리하기에 적합할 순 있어도 서버 쪽의 데이터들을 관리하기에는 적합하지 않은 점들이 있어서 등장하게 되었다.
ex)
- Client side's Data: input의 state등
- Server side's Data: DB에서 가져온 데이터
물론, Redux Middleware (Thunk, Saga, Observable) 등을 활용해서 서버 쪽의 데이터를 관리할 수는 있지만, thunk나 saga를 쓰다보면 보일러 플레이트가 많아, redux가 비대해지고 유지보수에 좋지 않다는 생각이 든다.
다시 한번 정리
개발을 하다보면 의문이 든다!
- 왜 API 호출을 다 redux 미들웨어를 활용해서 하려는 걸까?
- 특정 컴포넌트에서만 호출되는 API를, 왜 여러 컴포넌트에서 사용하려고 만든 전역 상태 라이브러리인 redux에서 관리해?
- 그렇다고 안넣자니 중구난방, 통일성에 좋지않음
→ 서버 데이터만 따로 관리할 수 있는 게 없을까?
사용하는 이유
저의 경우 서버로 부터 값을 가져오거나 업데이트 하는 로직을 store 내부에 개발하는 경우가 많습니다. 그렇다보니 store는 클라이언트 state를 유지해야하는데 어느 순간부터 store에 클라이언트 데이터와 서버 데이터가 공존 하게 됩니다. 그리고 그 데이터가 서로 상호작용하면서 서버 데이터도 클라이언트 데이터도 아닌 끔찍한 혼종(?)이 탄생하게 됩니다. (예를 들면 서버에는 이미 패치된 데이터가 클라이언트에서는 패치되기 전 데이터가 유저에게 사용되고 있는 것이라고 볼 수 있습니다.)
그래서 react-query를 사용함으로 서버, 클라이언트 데이터를 분리합니다. 이 개념에 대해 동의 하지 않아도 아래의 장점을 보신다면 사용하고 싶은 생각이 드실 것입니다.
react-query 장점
여러가지 장점이 있지만 주로 아래와 같이 프론트 개발자가 구현하기 귀찮은 일들을 수행합니다.
- 캐싱
- get을 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행한다. (예를 들면 게시판의 글을 가져왔을 때 게시판의 글을 생성하면 게시판 글을 get하는 api를 자동으로 실행 )
- 데이터가 오래 되었다고 판단되면 다시 get (invalidateQueries)
- 동일 데이터 여러번 요청하면 한번만 요청한다. (옵션에 따라 중복 호출 허용 시간 조절 가능)
- 무한 스크롤 (Infinite Queries (opens new window))
- 비동기 과정을 선언적으로 관리할 수 있다.
- react hook과 사용하는 구조가 비슷하다.
React Query Set-Up
react-query 설치
yarn add react-query
src/App.js
import React from "react";
import Router from "./shared/Router";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<Router />;
</QueryClientProvider>
); };
export default App;
간혹 index.js에 provider을 제공하는 경우가 있는데, 오류가 발생할 수 있으니 App.js에 Set-up하자.
useQuery
- 데이터를 get 하기 위한 api이다. (post, update는 useMutation을 사용한다.)
- 첫번째 파라미터로 unique Key(===query keys)가 들어가고, 두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다.
(당연한 말이지만 두번째 파라미터는 promise가 들어가야한다.) - 첫번째 파라미터로 설정한 unique Key는 다른 컴포넌트에서도 해당 키를 사용하면 호출 가능하다. unique Key는 string과 배열을 받습니다. 배열로 넘기면 0번 값은 string값으로 다른 컴포넌트에서 부를 값이 들어가고 두번째 값을 넣으면 query 함수 내부에 파라미터로 해당 값이 전달됩니다.
- return 값은 api의 성공, 실패여부, api return 값을 포함한 객체입니다.
- useQuery는 비동기로 작동합니다. 즉, 한 컴포넌트에 여러개의 useQuery가 있다면 하나가 끝나고 다음 useQuery가 실행되는 것이 아닌 두개의 useQuery가 동시에 실행됩니다. 여러개의 비동기 query가 있다면 useQuery보다는 밑에 설명해 드릴 useQueries를 권유드립니다.
- enabled를 사용하면 useQuery를 동기적으로 사용 가능합니다. 아래 예시로 추가 설명하겠습니다.
DB통신과 관련한 로직을 한곳에 모아놓는다.
src/api/todos.js or src/axios/todos.js
import axios from "axios";
const getTodos = async () => {
const response = await axios.get("http://localhost:3000/todos");
return response;
};
export { getTodos };
유지보수를 위해 DB통신관련 로직은 한 곳에 모아놓는 것이 좋다.
'내일배움캠프[4기_Reac트랙] > TIL' 카테고리의 다른 글
내일배움캠프 React트랙 55일차 회고 (2022.01.16) (0) | 2023.01.16 |
---|---|
내일배움캠프 React트랙 54일차 회고 (2022.01.13) (0) | 2023.01.16 |
내일배움캠프 React트랙 51일차 회고 (2022.01.10) (0) | 2023.01.11 |
내일배움캠프 React트랙 50일차 회고 (2022.01.09) (0) | 2023.01.09 |
내일배움캠프 React트랙 46일차 회고 (2022.01.03) (0) | 2023.01.04 |