RTK Query 웹 애플리케이션에서 데이터를 로드하는 일반적인 경우를 단순화해서 데이터를 가져오거나 캐시할수 있는 도구이다. RTK의 createSlice 및 createAsyncThunk 와 같은 RTK의 API를 활용하여 해당 기능을 구현한다.
store와 API Service 설정
API service 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Need to use the React-specific entry point to import createApi import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { Pokemon } from './types'
// Define a service using a base URL and expected endpoints 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 hooks for usage in functional components, which are // auto-generated based on the defined endpoints export const { useGetPokemonByNameQuery } = pokemonApi
RTK 쿼리를 사용하면 일반적으로 전체 API 정의를 한곳에서 정의해서 관심사를 모으고 추적하기 쉽도록 한다.
유지 보수하기 위해서 엔트포인트 별로 쿼리를 분리하고 싶을 수 도 있는데 그럴땐, create API 를 사용하여 base URL을 공통으로 갖고 endpoints 는 비어있는 함수로 정의하고 반환된 API에 injectEndpoints 를 사용하여 endpoint api 를 주입하는 방법으로 분리하여 관리 할 수 있다.
Add the service to your store
redux store에 reducer와 middleware 를 추가하고, Provider를 사용해 APP 에 store를 주입한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
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: { // Add the generated reducer as a specific top-level slice [pokemonApi.reducerPath]: pokemonApi.reducer, }, // Adding the api middleware enables caching, invalidation, polling, // and other useful features of `rtk-query`. middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(pokemonApi.middleware), })
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors // see `setupListeners` docs - takes an optional callback as the 2nd arg for customization setupListeners(store.dispatch)
Use the query in a component
useGetPokemonByNameQuery 를 사용하여 데이터의 상태와 데이터를 가져온다. isLoading , isFetching , isSuccess , isError 와 같은 데이터 상태에 bool 도 제공한다.
import * as React from 'react' import { useGetPokemonByNameQuery } from './services/pokemon'
export default function App() { // Using a query hook automatically fetches data and returns query values const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur') // Individual hooks are also accessible under the generated endpoints: // const { data, error, isLoading } = pokemonApi.endpoints.getPokemonByName.useQuery('bulbasaur')
return ( <div className="App"> {error ? ( <>Oh no, there was an error</> ) : isLoading ? ( <>Loading...</> ) : data ? ( <> <h3>{data.species.name}</h3> <img src={data.sprites.front_shiny} alt={data.species.name} /> </> ) : null} </div> ) }