RTK Query는 리더스 기반의 api 페칭 캐시관리 라이브러리 입니다. 장점으로는 리덕스의 보일러 플레이트와 캐시관리가 많이 줄어들었다는 것입니다.
기본 사용
contents.js
RTK 쿼리는 핵심 Redux Toolkit 패키지 설치에 포함되어 있습니다. 둘중 하나를 import해 사용하시면 됩니다.
import { createApi } from '@reduxjs/toolkit/query'
// OR
import { createApi } from '@reduxjs/toolkit/query/react'
일반적인 사용을 createApi위해 서버의 base URL과 상호 작용하려는 endpoint를 나열하는 "API 슬라이스"를 가져와 정의하는 것으로 시작합니다.
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
// 베이스 URL 및 엔드포인트를 사용하여 API를 정의합니다.
export const contentsApi = createApi({
reducerPath: 'contentsApi',
baseQuery: fetchBaseQuery({ baseUrl: '베이스 URL' }),
endpoints: (builder) => ({
getPokemonByName: builder.query({
query: (name) => `엔드포인트?name=${name}`,
}),
}),
})
// 기능 구성요소에 사용하기 위한 hook 내보내기
export const { useGetContentsApiQuery } = contentsApi
store.js
"API 슬라이스"에는 자동 생성된 Redux 슬라이스 리듀서와 구독 수명을 관리하는 사용자 지정 미들웨어도 포함되어 있습니다. 둘 다 Redux 스토어에 추가해야 합니다.
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { ContentsApi } from "./query/ContentsApi";
export const store = configureStore({
reducer: {
[ContentsApi.reducerPath]: ContentsApi.reducer,
},
// devTools도 물론 사용 가능합니다.
devTools: true,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(ContentsApi.middleware),
});
setupListeners(store.dispatch);
요청값 사용하기
자동 생성된 React hook를 구성 요소 파일로 가져오고 필요한 매개변수를 사용하여 구성 요소의 hook를 호출합니다. RTK 쿼리는 마운트 시 자동으로 데이터를 가져오고, 매개변수가 변경되면 다시 가져오고 {data, isFetching}
, 결과에 값을 제공하고, 해당 값이 변경되면 구성요소를 다시 렌더링합니다.
import { useGetContentsQuery } from "../../store/query/ContentsApi";
import { useState } from 'react';
const MainPage = () => {
const [value, setValue] = useState("")
const { data, isLoading, error, isFatching } = useGetContentsQuery(value);
// ...
}
data
: 해당 엔드포인트에 대한 요청의 결괏값isLoading
: true인 경우 쿼리가 현재 처음으로 로드 중이고 아직 데이터가 없음을 나타냅니다. 이것은 true시작된 첫 번째 요청에 대한 것이지만 후속 요청 에는 적용 되지 않고 false인 상태로 남아있습니다.error
: 오류가 났을 경우 오류의 결과를 알려줍니다.isFatching
: true인 경우 쿼리가 현재 가져오고 있지만 이전 요청의 데이터가 있을 수 있음을 나타냅니다. 이것은 true시작된 첫 번째 요청과 후속 요청 모두에 적용됩니다.
기본 캐시 동작
RTK 쿼리의 주요 기능은 캐시된 데이터의 관리입니다. 서버에서 데이터를 가져오면 RTK 쿼리는 Redux 저장소에 데이터를 '캐시'로 저장합니다. 동일한 데이터에 대해 추가 요청이 수행되면 RTK 쿼리는 서버에 추가 요청을 보내는 대신 기존 캐시된 데이터를 제공합니다.
요청이 시도될 때 데이터가 이미 캐시에 있는 경우 해당 데이터가 제공되고 새 요청이 서버로 전송되지 않습니다. 그렇지 않고 데이터가 캐시에 없으면 새 요청이 전송되고 반환된 응답은 캐시에 저장됩니다.
RTK Query는 보면 볼수록 매력이 있습니다. RTK Query는 기본적으로 캐싱데이터 관리를 따로 설정하지 않아도 해준다. 만약 구독이 제거되면(예: 데이터가 필요한 마지막 구성 요소가 마운트 해제될 때) RTK Query는 일정 시간(기본값 60초) 후에 데이터를 캐시에서 제거해 버린다. 사용자가 직접 조작을 할땐 KeepUnusedDataFor를 전체 적용 혹은 엔트포인트마다 개별 적용하면 된다.
만료시간 커스텀하기
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const ContentsApi = createApi({
reducerPath: "ContentsApi",
baseQuery: fetchBaseQuery({
baseUrl: "베이스 Url",
}),
endpoints: (builder) => ({
getContents: builder.query({
query: () => `엔드포인트`,
// 30초 후에 캐시에서 데이터를 삭제 아래의 구문이 없다면 기본 60초
keepUnusedDataFor: 30,
}),
}),
});
export const { useGetContentsQuery } = ContentsApi;
기본적으로 데이터는 구독자 참조 수가 0에 도달한 후 캐시에 60초 동안 유지됩니다. 이 값은 keepUnusedDataForAPI
정의 및 엔드포인트별 옵션을 사용하여 구성할 수 있습니다. 엔드포인트별 버전이 제공되는 경우 API 정의의 설정보다 우선 적용됩니다. 값을 keepUnusedDataFor초
단위로 제공하면 구독자 참조 수가 0에 도달한 후 데이터를 캐시에 보관해야 하는 기간을 지정합니다
데이터 다시 가져오기
refetchOnMountOrArgChange
는 캐시된 데이터를 대신 제공하는 추가 상황에서 다시 가져오기를 권장하는 데 사용됩니다. refetchOnMountOrArgChange
는 부울 값 또는 숫자를 초 단위 시간으로 사용합니다. 이 속성을 전달 true하면 쿼리에 대한 참조가 추가될 때 엔드포인트에서 항상 다시 가져옵니다. 즉, 후크를 호출하는 구성 요소가 마운트되거나 인수가 변경되면 해당 쿼리에 대한 새 참조를 추가하고 엔드포인트 + 인수 조합에 대한 캐시된 데이터가 이미 존재하는지 여부에 관계없이 항상 다시 가져옵니다. 초 단위로 값을 전달하면 다음 조건으로 동작이 실행됩니다.
- 쿼리 구독이 생성될 때:
- 캐시에 기존 쿼리가 있는 경우 해당 쿼리에 대해 현재 시간과 마지막으로 수행된 타임스탬프를 비교합니다.
- 제공된 시간(초)이 경과하면 다시 가져옵니다.
- 쿼리가 없으면 데이터를 가져옵니다.
- 기존 쿼리가 있지만 마지막 쿼리 이후 지정된 시간이 경과하지 않은 경우 기존 캐시된 데이터를 제공합니다.
데이터가 지정된 시간을 초과하는 경우 다시 가져오기
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
// global configuration for the api
refetchOnMountOrArgChange: 30,
endpoints: (builder) => ({
getPosts: builder.query({
query: () => `posts`,
}),
}),
})
요소가 마운트될 때 항상 강제로 다시 가져오기
import { useGetPostsQuery } from './api'
const Component = () => {
const { data } = useGetPostsQuery(
// 구성 요소가 마운트될 때 쿼리를 항상 가져오도록 강제 적용
{ refetchOnMountOrArgChange: true }
)
return <div>...</div>
}
조건부 가져오기
쿼리 후크는 구성 요소가 마운트되자마자 자동으로 데이터 가져오기를 시작합니다. 그러나 어떤 조건이 참이 될 때까지 데이터 가져오기를 지연해야 하는 사용 사례가 있습니다. RTK 쿼리는 해당 동작을 활성화하기 위해 조건부 가져오기를 지원합니다
skip
쿼리가 자동으로 실행되는 것을 방지하려면 후크에서 매개변수를 사용할 수 있습니다.
const MainPage = () => {
const [value, setValue] = useState("");
const [skip, setSkip] = useState(true);
const { data } = useGetContentsQuery(value, { skip });
// ...
}
skip가 true 일 때 다음과 같이 동작합니다.
- 쿼리에 캐시된 데이터가 있는 경우
- 캐시된 데이터 는 초기 로드에서 사용되지 않으며skip 조건이 제거 될 때까지 동일한 쿼리의 업데이트를 무시합니다.
- 쿼리 상태는uninitialized
- 쿼리에 캐시된 데이터가 없는 경우:
- 쿼리 상태는uninitialized
- 쿼리는 개발 도구로 볼 때 상태에 존재하지 않습니다.
- 쿼리는 마운트 시 자동으로 가져오지 않습니다.
반돤된 데이터 조작하기
개별 엔드포인트 는 쿼리 또는 변형이 캐시에 도달하기 전에 반환된 데이터를 조작할 수 createApi있는 transformResponse
속성을 허용합니다.
transformResponse해당 엔드포인트에 대해 성공적으로 baseQuery반환된 데이터와 함께 호출되고 반환 값은 transformResponse해당 끝점 호출과 연결된 캐시된 데이터로 사용됩니다. 기본적으로 서버의 페이로드는 직접 반환됩니다.이를 변경하려면 다음과 같은 기능을 사용해야 합니다.
transformResponse: (response, meta, arg) => response.some.deeply.nested.collection
실제 과제 적용 : api의 반환 결과가 문자열이여서 파싱을 한번 거쳐서 반환하였습니다.
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const ForestApi = createApi({
reducerPath: "ForestApi",
baseQuery: fetchBaseQuery({
baseUrl:
"휴양림API",
}),
endpoints: (builder) => ({
getContents: builder.query({
query: (page) => `휴양림 엔드포인트/pageNo=${page}`,
transformResponse: (response) => JSON.parse(response),
}),
}),
});
export const { useGetContentsQuery } = ForestApi;
'Pre Onboarding' 카테고리의 다른 글
[RTK Query] 캐싱 (0) | 2022.03.03 |
---|---|
RTK Query 엔드포인트 url 변수로 변경하기 및 데이터 조작하기 (0) | 2022.02.28 |
[PreOboadring] CANVAS (0) | 2022.02.24 |
[PreOnboarding] 번들링과 웹팩 (0) | 2022.02.23 |
[PreOnboarding] RTK Query를 사용해보자 (0) | 2022.02.23 |
댓글