React Query 왜 쓰는지 이해하기
# React Query 무엇일까요? 그리고 왜 쓰는걸까요?
2024년 04월 08일
리액트 쿼리란?
React-Query는 React 및 Next.js 애플리케이션에서 데이터 처리를 간편화하는 라이브러리로, 데이터 관리, 동기화, 업데이트를 쉽게 처리할 수 있도록 돕는다. 이는 비동기 로직을 직관적으로 다룰 수 있게 하며, 복잡한 코드를 작성하지 않아도 되어 React, Next.js 컴포넌트 내에서 API를 간편하게 사용할 수 있다. React-Query는 서버 데이터를 가져오고 업데이트하는 과정을 간소화하여 개발자가 데이터를 쉽게 다룰 수 있도록 지원한다.
Server state
Server state는 클라이언트 애플리케이션이 서버로부터 데이터를 가져와(빌려와서) 이를 상태로 관리하는 것을 의미한다. 해당 상태는 주로 API 요청을 통해 서버로부터 가져온 데이터를 포함하며, 일반적으로 비동기 작업을 통해 관리된다. server state는 서버와의 상호작용을 통해 동적으로 데이터를 업데이트하고 사용자에게 최신 정보를 제공하는 역할을 하게 된다.
Server state의 특징
- 비동기: Server state는 API 요청과 같은 비동기 작업을 통해 데이터를 가져오므로 비동기적 특성을 가지게 되므로 데이터가 로딩 중이거나 에러가 발생했을 때 이러한 상태를 관리해야 한다.
- 일시적: 서버로부터 최신 데이터를 가져오는 것이기 때문에, 데이터가 자주 변동될 수 있으므로 캐싱, 리패칭 등의 전략이 필요하다
- 동기화 필요: 서버 상태는 클라이언트와 서버 간의 데이터 동기화가 필요하다. 서버의 데이터 변경 사항을 반영하기 위해 주기적으로 데이터를 다시 가져와야 최신의 데이터를 사용자에게 보여줄 수 있을것이다.
❗ 한 문장으로 요약해보자면, Server state는 클라이언트가 서버와 비동기 API 요청으로 데이터를 주고받아 동적으로 관리하는 일시적이고 동기화가 필요한 상태를 의미한고 생각하면 된다.
Client state
클라이언트가 자체적으로 만드는 상태로, 클라이언트가 소유하고 제어하는 데이터를 의미한다
- 일반적으로 사용자 인터페이스(UI)와 밀접하게 관련되어 있으며, 모달 창의 열림/닫힘 상태, 사용자가 클릭한 버튼, 현재 창의 크기 변화 등과 같은 메타 정보를 포함한다.
- 예를 들어, 사용자가 버튼을 클릭하면 해당 버튼의 열림 상태가 변경되거나, 사용자가 드롭다운 메뉴를 열면 해당 메뉴의 상태가 open으로 설정되는 것 등이 있다.
- 리액트에서는
useState
훅을 사용하여 이러한 상태를 관리할 수 있다.
기존 Server state 관리의 문제점
- 비동기 데이터 처리의 복잡성
- 서버에서 데이터를 가져오는 작업은 비동기적으로 이루어지는데 이를 관리하기 위해
useEffect
와useState
를 사용하지만, 로딩 상태, 에러 상태, 성공 상태 등을 추가로 처리해야 하므로 코드가 복잡해진다. - 서버와의 데이터 동기화가 필요할 때마다 별도로 코드를 작성해야 한다.
- 전역 상태 관리의 부담
- Server state를 여러 컴포넌트에서 필요로 할 때, 각 컴포넌트에서 개별적으로 API 호출을 하는 것은 큰 비용 낭비가 일어난다.
- Redux와 같은 전역 상태 관리 라이브러리를 사용할 경우, 서버에서 데이터를 받아와 상태 관리를 하기 위해 Redux-Saga, Redux-Thunk 같은 미들웨어를 사용하는 것이 필요하는데, 이로 인해 관련 로직 및 모듈이 비대해지고, 초보자에게는 높은 런닝커브가 된다.
- 데이터 일관성 문제
- API 요청 시점에서 받아온 데이터는 호출 할 때 가져온 그 순간의 데이터에 불과하여, 시간이 지남에 따라 데이터가 오래되어 신뢰할 수 없는 데이터가 된다.
리액트 쿼리의 등장
이러한 Server state 상태 관리의 문제점을 해결하기 위해 React Query가 등장했다.
비동기 데이터 처리의 간소화
React Query는 데이터 페칭, 캐싱, 동기화, 업데이트를 손쉽게 처리할 수 있는 기능을 제공하여 상태 관리 로직을 단순화한다. useQuery
라는 훅을 사용하면 데이터 요청, 로딩 상태, 에러 처리를 매우 간단하게 구현할 수 있어 코드가 깔끔해지고 유지보수가 쉬워진다.
자동 캐싱 및 중복 데이터 페칭 방지
동일한 데이터를 여러 컴포넌트가 필요로 할 때, React Query는 단일 API 요청으로 데이터를 페칭하고 이를 캐싱하여 중복된 API 호출을 방지한다. 전역적으로 캐싱된 데이터는 필요로 하는 다른 컴포넌트에서 쉽게 사용할 수 있다.
React Query에서의 캐싱
- 자동 캐싱: 서버로부터 데이터를 가져오면 자동으로 캐시한다. 동일한 데이터 요청이 있을 경우, 캐시된 데이터를 사용하여 빠르게 응답할 수 있다.
- 캐시 유효성 관리: 데이터가 변경되거나 유효 시간이 만료되면 캐시를 무효화하고 새로운 데이터를 가져온다.
staleTime
과cacheTime
옵션을 사용하여 캐시 유효 기간을 설정할 수 있다. - 데이터 동기화: 백그라운드에서 데이터를 자동으로 리패칭하여 캐시된 데이터와 서버 데이터를 동기화한다.
💡 정리하자면, React Query는 기존 서버 상태 관리의 복잡성과 비효율성을 해결해주며, 데이터 패칭과 캐싱, 데이터 업데이트를 간편하게 처리할 수 있어 프로젝트의 신뢰성과 성능을 향상시킬 수 있다는 장점이 있다.
리액트 쿼리가 기존 전역 상태 라이브러리를 완전히 대체할 수 있을까?
이처럼 리액트 쿼리는 서버 상태 관리에서 데이터 페칭, 캐싱, 동기화 및 업데이트를 간편하게 처리할 수 있는데, 간편한 사용법과 강력한 기능으로 인해 기존 전역 상태 관리 라이브러리인 Redux나 Zustand를 대체할 수 있지 않을까 하는 의문이 들었다.
결론은 리액트 쿼리와 전역 상태 관리 라이브러리인 Redux, Zustand는 각각의 용도와 장점이 다르기 때문에 리액트 쿼리가 전역 상태 라이브러리를 완전히 대체한다고 보기보다는, 각각의 장점을 이해하고 적절히 조합하여 최대한 활용하는 것이 중요하다.
- 서버 상태 관리:
- React Query를 사용하여 서버 상태를 효율적으로 관리하고, 데이터 페칭과 캐싱, 동기화를 간편하게 처리, 즉 비동기 데이터 패칭의 서버 상태 관리에 유용
- 전역 클라이언트 상태 관리:
- Redux나 Zustand와 같은 전역 상태 관리 라이브러리를 사용하여 사용자 인터페이스와 관련된 상태를 중앙에서 관리
💡리액트 쿼리를 상태 관리를 위한 라이브러리라고 생각하기보다는, 비동기 데이터 관리를 도와주는 툴이라고 생각하면 된다. 실제로, 리액트 쿼리는 서버에서 데이터를 가져오고 이를 관리하는 작업을 간단하게 만들어주지만, 전역 클라이언트 상태 관리와는 다른 목적을 가지게 된다.