-
[React] React-Query의 개념 및 예제FrontEnd/React 2023. 3. 2. 11:27
React Query는 API 통신과 비동기 데이터 관리에 사용되는 React 라이브러리 입니다.
1. React-Query 이전
- state에 비동기 데이터를 보관할 경우
- 다수의 component의 lifecycle에 따라 비동기 데이터가 관리되기 때문에 캐싱 등 최적화를 하기 어려움
- 다수의 component에서 동일한 API를 호출하거나, 특정 API응답이 다른 API에 영향을 미치는 경우 등에 대응하기 어려움
- Redux를 사용하여 비동기 데이터를 관리할 경우
- componet의 lifecycle과 관계없이 비동기 데이터를 관리할 수 있어 최적화가 쉬우며 복잡한 사용자 시나리오에도 대응 가능
- 장황한 Boilerplate 코드로 인해 비동기 Action 처리에 복잡성 증가
- Redux는 API 통신 및 비동기 상태 관리를 위한 라이브러리가 아니라 Global State Management Library, 즉 전역 상태 관리 라이브러리이기 때문에 API 요청 수행을 위한 규격화된 방식 부재
- 사용자 경험 향상을 위한 복잡한 시나리오를 수행하는데 많은 개발 리소스 소모
2. React-Query란?
- React Application에서 서버의 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트 하는 작업을 도와주는 라이브러리
- 우리에게 친숙한 Hook을 사용하여 React Component 내부에서 자연스럽게 서버(또는 비동기적인 요청이 필요한 Source)의 데이터를 사용할 수 있는 방법을 제안
- API 요청을 Query 그리고 Mutation 이라는 두 가지 유형으로 나누어 생각
3. Query 요청 개요
const { status, data, error } = useQuery( queryKey, // 이 Query 요청에 대한 응답 데이터를 캐시할 때 사용할 Unique Key (required) fetchFn, // 이 Query 요청을 수행하기 위한 Promise를 Return 하는 함수 (required) options, // useQuery에서 사용되는 Option 객체 (optional) );
- status
- isLoading or status === 'loading' - 데이터가 없거나 아직 fetch 중일 때
- isError or status === 'error' - 데이터를 불러오는 과정에서 error를 호출할 때
- isSuccess or status === 'success' - 성공적으로 데이터를 불러왔을 때
- isIdle or status === 'idle' - The query is currently disabled (you'll learn more about this in a bit)... 잘 모르겠음..?
- error
- isError state에 도달 하면 반환하는 객체
- data
- isSuccess state에 도달하면 반환하는 객체(데이터)
- isFetching
- 아직 query가 진행 중이면 isFetching은 true를 반환
4. Query Key
- Query Key는 string이거나 string이나 nested object로 이루어진 배열로, Query Key를 통해 React Query는 데이터를 캐싱하고 관리한다.
// string query keys useQuery('todos', ...) // queryKey === ['todos'] // array query keys useQuery(['todo', 5], ...) // queryKey === ['todo', 5] useQuery(['todo', 5, { preview: true }], ...) // queryKey === ['todo', 5, { preview: true }] useQuery(['todos', { type: 'done' }], ...) // queryKey === ['todos', { type: 'done' }] // array key에서 순서가 바뀌면 다른 키 // ex) 같은 키 useQuery(['todos', { status, page }], ...) useQuery(['todos', { page, status }], ...) // ex) 다른 키 useQuery(['todos', status, page], ...) useQuery(['todos', page, status], ...) // variable이 바뀔 경우에 query를 호출 하고 싶으면 query key에 variable을 담는다. (변수 의존) function Todos({ todoId }) { const result = useQuery(['todos', todoId], () => fetchTodoById(todoId)) }
5. Query Function
promise를 반환하는 fuction으로 비동기 요청으로 받은 데이터나 에러를 반환한다.
// 다음과 같은 방법 모두 사용 가능하다. useQuery(['todos'], fetchAllTodos) useQuery(['todos', todoId], () => fetchTodoById(todoId)) useQuery(['todos', todoId], async () => { const data = await fetchTodoById(todoId) return data }) useQuery(['todos', todoId], ({ queryKey }) => fetchTodoById(queryKey[1]))
6. useQueries
useQuery의 호출 수가 render마다 바뀌는 경우, hook rule을 위반하기 때문에 수동으로 useQuery를 사용할 수 없다. 이때 useQueries를 사용하여 동적으로 query를 호출한다.
function App({ users }) { const userQueries = useQueries( users.map(user => { return { queryKey: ['user', user.id], queryFn: () => fetchUserById(user.id), } }) ) }
React.Suspense모드를 사용할 때도 suspense = true를 적용하여 로딩 상태 처리를 useQuery에서 처리하지 않도록 할 수 있다.
'FrontEnd > React' 카테고리의 다른 글
[React] Three.js + CSS3d animation (1) 2023.04.24 [React] React Architecture 정리 (0) 2023.03.07 [React] 페이지 이동시, 파라미터 전달 및 취득 방법 (2) 2023.02.20 [React] Vite 기반 프로젝트에서 동적 import로 이미지 불러오기 (0) 2023.02.11 [React] 좋은 Frontend Devloper가 되기 위한 정리 (1) 2023.02.11 - state에 비동기 데이터를 보관할 경우