[React Query] useQuery - isLoading vs isFetching (feat. isPending, isInitialLoading)

SSO·2024년 5월 13일
1

Web-Develop-Study

목록 보기
15/18

리액트 쿼리로 로딩 상태를 관리해 본 경험이 있는데.... 언제부터인가 기억이 안나서 포스팅을 다시 해보려한다.
(사실 저렇게 로딩 상태를 관리하는게 올바른 방법인지도 모르겠지만... 사용해 본 건 알아야 하니까용.. 제 방법이 옳지 않답니다..😶)

📌 React Query란

React Query는 상태 관리 라이브러리 이면서 데이터 Fetching, Caching, 동기화, 서버 업데이트 등을 쉽게 만들어준다.

[React Query]에 대해서 알아보자!

이전에 포스팅에서 리액트 쿼리에 대해서는 간단하게 다뤘으므로 isLoading과 isFetching의 차이에 대해서 바로 알아보자:)


📌 isFetching vs isLoading

우선 isLoading과 isFetching은 useQuery 훅으로 불러올 수 있다.

useQuery훅은 GET 요청과 같이 서버로부터 데이터 조회 시 사용할 수 있다.

그럼 이 둘의 차이는 뭘까?

💡 isFetching

isFetching은 어떤한 요청 내부의 비동기 함수가 처리되었는지 여부에 따라서 true/false로 나누어진다.
캐시에 저장된 데이터가 없거나, cacheTime을 지정한 시간이 지나고나서 재요청이 일어날 때 isFetching 값이 true가 된다.
일반적으로 isFetching속성은 모든 API요청이 일어나면 상태가 변경된다.


💡 isLoading

isLoading캐시된 데이터조차 없이, 처음 실행된 쿼리일 때 로딩 여부에 따라 true/false로 나누어진다.

내가 적용한 경우가 isLoading을 사용한 경우이다. 데이터를 처음 불러올 때는 데이터를 가져오는 동안 보여줄 데이터가 없으므로 isLoadingtrue인 경우에는 '로딩중' 이라는 글씨를 보여주고 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부터는 loadingpending으로 변경되었다.
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이다!

isInitialLoading속성은 캐시에 저장된 데이터가 없거나, cacheTime을 지정한 시간이 지나고나서 재요청이 일어날 때 true가 된다.

isInitialLoading은 (isFetching&&isLoading)과 동일한 결과를 가진다.

공식문서에 나와 있는 내용을 보면 isLoading을 로딩 여부를 위한 flag로 사용하는 것은 권장되지 않는다.
그 대신 isInitialLoading을 사용하는게 권장된다.
isFetching && isLoading 이 의미는 곧 데이터가 없는(=isLoading) 쿼리를 요청(=isFetching)하면 결국 true를 반환할 것이기 때문이다.

(위에서 내가 처음 했던 방식이 좋은 방식이 아니라는 결론이 나왔다...ㅎㅎ)



앞으로 비슷한 기능을 다시 구현하게 된다면 isInitialLoading사용을 해봐야겠다.
덕분에 isFetching과 isPending(isLoading)에 대해 알 수 있었다.

포스팅 끝!

profile
👩🏻‍💻👊🏻⭐️

0개의 댓글