리액트 쿼리로 로딩 상태를 관리해 본 경험이 있는데.... 언제부터인가 기억이 안나서 포스팅을 다시 해보려한다.
(사실 저렇게 로딩 상태를 관리하는게 올바른 방법인지도 모르겠지만... 사용해 본 건 알아야 하니까용.. 제 방법이 옳지 않답니다..😶)
React Query는 상태 관리 라이브러리 이면서 데이터 Fetching, Caching, 동기화, 서버 업데이트 등을 쉽게 만들어준다.
이전에 포스팅에서 리액트 쿼리에 대해서는 간단하게 다뤘으므로 isLoading과 isFetching의 차이에 대해서 바로 알아보자:)
우선 isLoading과 isFetching은 useQuery
훅으로 불러올 수 있다.
useQuery훅은 GET 요청과 같이 서버로부터 데이터 조회 시 사용할 수 있다.
그럼 이 둘의 차이는 뭘까?
isFetching
은 어떤한 요청 내부의 비동기 함수가 처리되었는지 여부에 따라서 true/false
로 나누어진다.
캐시에 저장된 데이터가 없거나, cacheTime을 지정한 시간이 지나고나서 재요청이 일어날 때 isFetching
값이 true
가 된다.
일반적으로 isFetching
속성은 모든 API요청이 일어나면 상태가 변경된다.
isLoading
은 캐시된 데이터조차 없이, 처음 실행된 쿼리일 때 로딩 여부에 따라 true/false
로 나누어진다.
내가 적용한 경우가 isLoading
을 사용한 경우이다. 데이터를 처음 불러올 때는 데이터를 가져오는 동안 보여줄 데이터가 없으므로 isLoading
이 true
인 경우에는 '로딩중' 이라는 글씨를 보여주고 false
되면 그 때 불러온 데이터를 보여주도록 했다.
const fetchData = async () => {
const apiUrl = "http://localhost:3001/items";
const response = await axios.get(apiUrl);
return response.data;
};
const ProductList = () =>
const { data: items, isLoading } = useQuery<Product[]>("product", fetchData);
// 로딩중일 경우
if (isLoading) {
return (
<p>목록을 불러오고 있습니다.</p>
);
}
이후 다른 컴포넌트에서 isLoading
값을 가져오고 싶다면 쿼리키를 사용해서 가져와 사용하면 된다.
const { isLoading: productListLoading } = useQuery("product");
=> 즉, isLoading과 isFetching은 비슷하게 로딩이라는 개념을 사용하지만 isLoading은 처음 데이터를 불러올 때(=캐시된 데이터가 없을 때)사용하며 isFetching은 캐시된 데이터가 있지만 데이터를 다시 가져와야 할 경우에 사용한다.
❗️주의사항
이전에 구현했던 기능이다 보니 isLoading으로 명시를 해놨으나 React-Query v5부터는loading
이pending
으로 변경되었다.
ex.isLoading
=>isPending
최신 버전을 사용하게 된다면 유의하면 좋을 것 같다!
isLoading
(isPending
)속성은 한 가지 불편한 점이 있다.
그건 useQuery의 enabled
속성을 사용할 때이다.
enabled: 지정한 조건이 참인 경우에만 요청을 수행한다.
const useFetchData = (id) => {
const { data, isLoading, isFetching } = useQuery({
queryKey: 'product',
queryFn: fetchProduct,
enabled: id > 0,
});
}
useFetchData(-1);
useFetchData(1);
이렇게 실행을 해보면 id가 -1이 들어가면 enabled
조건에 맞지 않으므로 요청이 가지 않을 것이다.
하지만 실행해보면 isLoading
의 결과는 모두 true
로 뜨고 isFetching
의 결과는 각각 false, true
로 잘 뜬다.
이러한 문제를 해결하기 위해서 나온게 isInitialLoading
이다!
isInitialLoading
속성은 캐시에 저장된 데이터가 없거나, cacheTime을 지정한 시간이 지나고나서 재요청이 일어날 때 true
가 된다.
isInitialLoading은 (isFetching&&isLoading)과 동일한 결과를 가진다.
공식문서에 나와 있는 내용을 보면 isLoading
을 로딩 여부를 위한 flag로 사용하는 것은 권장되지 않는다.
그 대신 isInitialLoading을 사용하는게 권장된다.
isFetching && isLoading
이 의미는 곧 데이터가 없는(=isLoading
) 쿼리를 요청(=isFetching
)하면 결국 true
를 반환할 것이기 때문이다.
(위에서 내가 처음 했던 방식이 좋은 방식이 아니라는 결론이 나왔다...ㅎㅎ)
앞으로 비슷한 기능을 다시 구현하게 된다면 isInitialLoading사용을 해봐야겠다.
덕분에 isFetching과 isPending(isLoading)에 대해 알 수 있었다.
포스팅 끝!