RTK Query Basic

RTK Query

RTK Query 웹 애플리케이션에서 데이터를 로드하는 일반적인 경우를 단순화해서 데이터를 가져오거나 캐시할수 있는 도구이다. RTK의 createSlicecreateAsyncThunk 와 같은 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 도 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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>
)
}