RTK Query?
RTK Query는 데이터를 fetching, caching을 할 수 있는 툴이다. 웹에서 데이터를 가져오는 것을 간단하게 만들어 데이터 패치(가져오기)와 캐싱 로직을 작성할 필요가 없어지게 한다.
RTK-Query는 Redux-Toolkit 패키지에 포함되어있는 선택적인 추가 기능이다.
웹 애플리케이션은 일반적으로 서버에서 데이터를 가져오게되고, 데이터 업데이트 및 클라이언트의 캐시 된 데이터를 서버 데이터와 동기화된 상태로 유지해야 한다.
RTK-Query는 Apollo Client, React Query, Urql 및 SWR과 같이 데이터 가져오기를 위한 선구적인 솔루션 제공 및 API 디자인에 고유한 접근 방식을 추가한다.
RTK Query 특징
- 데이터 패칭(가져오기) 및 캐싱 로직은 Redux Toolkit createSlice 및 createAsyncThunk API를 기반으로 구축된다.
- Redux Toolkit은 UI에 구애받지 않기 때문에 RTK Query의 기능은 모든 UI 계층에서 사용할 수 있다.
- API 엔드포인트는 인수에서 쿼리 매개변수를 생성하고 캐싱을 위해 응답을 반환하는 방법을 포함하여 미리 정의된다.
- RTK 쿼리는 전체 데이터 패칭 프로세스를 캡슐화해 data와 isLoading필드를 컴포넌트에게 제공하고, 컴포넌트가 mount, unmount시 캐시된 데이터의 수명을 관리하는 React Hook를 생성할 수 있다.
- RTK 쿼리는 초기 데이터 패칭 후 웹 소켓 메시지를 통한 캐시 업데이트 스트리밍 같은 상황을 위해 "cache entry lifecycle"이라는 옵션을 제공한다.
- OpenAPI 및 GraphQL 스키마에서 API슬라이스 코드에대한 예시를 제공한다.
- RTK 쿼리는 타입스크립트로 만들어졌고, 완벽한 TS경험을 제공한다.
RTK-Query APIs
위에서 말했듯 RTK-Query는 RTK 패키지에 포함되어 있다. 아래 두 가지 중 하나를 통해 사용할 수 있다.
import { createApi } from '@reduxjs/toolkit/query'
// 리액트 엔트리 포인트를 명시하면 자동으로 정의된 엔드포인트의 훅을 생성합니다
import { createApi } from '@reduxjs/toolkit/query/react'
RTK Query의 API를 설명하자면
- createApi() : RTK 쿼리의 기능의 핵심이다. 데이터를 패치 및 변환하는 설정을 포함 엔드포인트들에서 어떻게 데이터를 패치하는지 정의할 수 있다. 대부분은 베이스 URL 하나당 하나의 API Slice를 사용한다.
- fetchBaseQuery() : 간단한 요청을 위한 fetch의 wrapper이다. 대부분의 사용자에게 createApi의 baseQuery로 사용된다.
- <ApiProvider /> : 리덕스 스토어가 없다면 Provider로 사용가능하다.
- setupListeners() : refetchOnMount와 refetchOnReconnect를 사용하기 위한 유틸
번들 사이즈
RTK-Query는 고정된 크기를 앱의 번들 사이즈에 추가한다. Redux-Toolkit과 React-Redux위에서 빌드하기 때문에, 얼마나 사용하는지에 따라 사이즈가 달라진다.
예상되는 min+gzip 번들 사이즈는 다음과 같다.
- RTK 사용 중이면 : RTK Query ~9kb, hooks ~2kb
- RTK를 사용 중이지 않는다면 :
- React 없음 : RTK+dependencies+RTK Query 17kb
- React 있음 : 19kb + React-Redux(peer dependency)
엔드포인트는 endpoint내의 코드의 크기를 추가하며 일반적으로는 몇 바이트에 불과하다.
RTK-Query로 직접 작성한 데이터 패칭 로직을 제거하면 대부분의 애플리케이션 사이즈가 개선된다.
사용 방법
createAPI 정의
전형적으로 사용하는 방법은 먼저 createAPI를 정의한다.
import { createApi } from '@reduxjs/toolkit/query'
// 리액트 엔트리 포인트를 명시하면 자동으로 정의된 엔드포인트의 훅을 생성합니다
import { createApi } from '@reduxjs/toolkit/query/react'
APISlice 생성
createAPI 정의 이후 API Slice를 정의한다.
서버의 baseUrl과 우리가 접근하고 싶은 엔드포인트의 리스트를 정의한다.
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { Pokemon } from './types'
// base URL과 엔드포인트들로 서비스 정의
export const pokemonApi = createApi({
reducerPath: 'pokemonApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (builder) => ({
getPokemonByName: builder.query<Pokemon, string>({
query: (name) => `pokemon/${name}`,
}),
}),
})
// 정의된 엔드포인트에서 자동으로 생성된 훅을 함수형 컴포넌트에서 사용하기 위해 export
export const { useGetPokemonByNameQuery } = pokemonApi
Store 설정
API slice를 리덕스 스토어에 추가해주어야 한다. 커스텀 미들웨어도 store에서 추가해줄 수 있다.
import { configureStore } from '@reduxjs/toolkit'
// Or from '@reduxjs/toolkit/query/react'
import { setupListeners } from '@reduxjs/toolkit/query'
import { pokemonApi } from './services/pokemon'
export const store = configureStore({
reducer: {
// 특정 top-level slice에서 생성된 리듀서를 추가
[pokemonApi.reducerPath]: pokemonApi.reducer,
},
// 캐싱, 요청 취소, 폴링 등등 유용한 rtk-query의 기능들을 위한 api 미들웨어 추가
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(pokemonApi.middleware),
})
// 옵셔널, refetchOnFocus/refetchOnReconnect 기능을 위해 필요함
// setupListeners 문서를 참고 - 커스텀을 위한 옵셔널 콜백을 2번째 인자로 받음
setupListeners(store.dispatch)
컴포넌트에서 Hooks 사용
API Slice에서 자동 생성된 hooks을 import 하고 필요한 파라미터와 함께 hooks 호출한다.
RTK Query는 자동으로 컴포넌트가 마운터 될 때 데이터를 패치, 파라미터가 바뀔 때 다시 패치를 하여 {data, isFetching} 값을 제공하고 컴포넌트를 리 렌더링 한다.
import * as React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'
export default function App() {
// 자동으로 데이터를 패치하고 쿼리 값을 가져오는 쿼리 hook을 사용
const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur')
// 각각의 hooks은 생성된 엔드포인트에서도 접근 가능함
// const { data, error, isLoading } = pokemonApi.endpoints.getPokemonByName.useQuery('bulbasaur')
// 데이터와 로딩 상태에 따라 UI를 렌더링
}
RTK-Query의 개요와 기본적인 API들을 알아보았다.
아직 기본적인 개념들이고 직접 사용해서 구현해보지 않아서 와닿지는 않는다
다음 포스팅에는 직접 실습해보면서, 알아봐야겠다.
'개발 > React' 카테고리의 다른 글
[React] 디바운스(Debounce), 쓰로틀(Throttle) (0) | 2023.03.19 |
---|---|
Next + RTK + Typescript 개발 환경 설정하기 (0) | 2022.11.18 |
[React] Redux-Toolkit 대표적인 API 알아보기 (0) | 2022.10.04 |
[React] Redux-Toolkit Quick Start 공식 문서 따라하기 (1) | 2022.10.04 |
리액트 가상 DOM(React Virtual Dom) (0) | 2022.09.28 |
댓글