-
[React] Tanstack react-query 데이터 리패칭의 네가지 방법Java Script & Type Script 2023. 12. 28. 18:23728x90
React query를 도입하며 느낀 가장 큰 장점은 물론 서버요청의 캐싱였고, 두번째로는 useState를 이용할 필요도, useEffect를 이용해 렌더링되자마자 함수를 호출할 필요없게해주기 때문에 리소스를 줄일 수 있다는 점이었습니다.
저는 컴포넌트의 생명주기와 관련된 사이드이펙트를 처리하는 useEffect 훅을 통해 state간의 유기적인 연결을 하는 것을 좋아하는데요,
오랜만에 useQuery를 사용하려다보니 useEffect의 의존성배열을 직접 관리하지 않고 state가 변할 때 마다 refetch를 어떻게 할 수 있는지 단번에 떠오르지가 않았어요.
찾아보니 useQuery내에서 refetch하는 기능을 다양하게 제공하고있었습니다.
1. useQuery의 enabled 옵션
특정 조건에 따라 쿼리의 실행을 제어할 수 있습니다. enabled 옵션을 이용해 조건이 충족될 때만 쿼리가 실행되도록 설정할 수 있습니다.
const { data, isLoading, error } = useQuery(['queryKey_name', queryParam], fetchData, { enabled: queryParam !== null, // queryParam이 null이 아닐 때만 쿼리 실행 });
만약 여기서 useQuery를 쓰지 않고 useState와 useEffect를 사용한다면
const [data, setData] = React.useState(null); const [isLoading, setIsLoading] = React.useState(true); const [error, setError] = React.useState(null); const [queryParam, setQueryParam] = React.useState(/* initial value */); React.useEffect(() => { const fetchData = async () => { setIsLoading(true); setError(null); try { const response = await yourApiCall(queryParam); setData(response.data); } catch (error) { setError(error); } finally { setIsLoading(false); } }; if (queryParam !== null) { fetchData(); } return () => { // cleanup logic }; }, [queryParam]); // queryparam이 변하면 다시 실행됩니다
이 엄청난 코드 길이의 차이 (박과 박과 쿼리로 박과)...
2. queryKey 변경
React Query는 queryKey가 변경될 때마다 자동으로 쿼리를 다시 실행합니다. queryKey에 의존성을 포함시키면, 이 값이 변경될 때마다 쿼리가 다시 실행됩니다.
const { data, isLoading, error } = useQuery(['queryKey', dependency], fetchData);
여기서 dependency값이 변경될 때마다 쿼리가 다시 실행됩니다.
3. refetch 메소드
React Query의 반환값 중 하나인 refetch 함수를 사용하여 명시적으로 쿼리를 다시 실행할 수 있습니다. 예를 들어, 버튼 클릭과 같은 이벤트 핸들러 내에서 refetch를 호출할 수 있습니다.
const { data, isLoading, error, refetch } = useQuery('queryKey', fetchData); // 필요한 상황에서 호출 (주로 post,patch 로직완료 후 ) refetch();
4. useQueryClient와 invalidateQueries
특정 쿼리 또는 모든 쿼리를 수동으로 무효화하여 다시 가져올 수 있습니다. useQueryClient 훅을 사용하여 쿼리 클라이언트에 접근한 다음, invalidateQueries 메소드로 특정 쿼리를 무효화합니다. (진짜 삽질 한참하다가 이걸로 해결한 적 있음)
import { useQuery, useQueryClient } from 'react-query'; const queryClient = useQueryClient(); const { data, isLoading, error } = useQuery('queryKey', fetchData); // 쿼리 무효화 및 다시 가져오기 queryClient.invalidateQueries('queryKey');
예를 들어, 유저가 post, patch의 발생시킴으로써 새로운 데이터가 생성되거나 기존 데이터가 수정된 후, 관련된 쿼리를 무효화하여 최신 상태의 데이터를 반영하고자 할 때 invalidateQueries를 사용할 수 있습니다.
post, patch, delete과 같이 데이터를 변경하는 로직 이후에 invalidateQueries를 호출하면 변경된 데이터를 즉각적으로 바영하기 위해 해당 쿼리를 다시 실행시키고 캐시를 업데이트할 수 있습니다.
헷갈리는 staleTime vs cacheTime
function useFetchData(queryKey, url) { const { data, isLoading, error } = useQuery(queryKey, async () => { const response = await fetch(url); return response.json(); }, { staleTime: 5 * 60 * 1000, // 5분 동안 데이터는 신통 상태로 간주되지 않음 cacheTime: 30 * 60 * 1000 // 비활성화 후 30분 동안 캐시에 데이터 유지 }); return { data, isLoading, error }; }
- stale time이 5분 → 데이터가 처음 가져와진 후 5분 동안은 자동으로 재요청되지 않음
- cache time이 30분 → 쿼리가 비활성화된 후에도 30분 동안은 캐시에 데이터가 유지되도록 함
즉, staleTime은 언제까지 데이터가 유효하다고 간주되어 재요청을 트리거하지 않을지에 대한 시간이고,
cacheTime은 데이터가 캐시에서 비활성화되기까지의 시간입니다.
728x90'Java Script & Type Script' 카테고리의 다른 글
[Next.js] App Router의 신기능, Private Folder & Route Group (Next.js 폴더구조 잡기), File (0) 2024.01.28 [React] 디자인패턴 Custom hook Pattern-UI와 비즈니스로직의 분리에 대하여 (0) 2024.01.20 [클린코드] 추상화, 관심사의 분리,의존성주입 (Java script version) (0) 2023.07.27 [자료구조] Map과 Set (0) 2023.07.10 [JS] 내가 몰랐던 ES6 최신문법 (0) 2023.07.10