초보 개발자의 성장 일기

데이터 fetch 후 map을 하면 읽을 수 없는 이유 본문

Development/React JS

데이터 fetch 후 map을 하면 읽을 수 없는 이유

YUNA 2024. 1. 10. 20:53

API를 fetch하고 데이터를 map으로 할당하다보면

제대로 데이터를 불러왔지만 map을 읽을 수 없다는 오류를 보게된다.

 

이때 data를 console로 찍으면 빈 배열이 나오게 된다.

이유가 무엇일까?

 

데이터를 fetch하는 함수가 비동기식이기 때문이다.

데이터를 불러오기전에 데이터를 할당 해 데이터의 할당 항목을 알 수 없는 것이었다.

 

이것은 간단하게 해결이 가능하다.

if (!data) return <div></div>;
 

데이터가 없으면(즉 거짓이면) 빈 <div>를 넣는 것이다.

데이터가 있을 때는 if안의 값이 거짓이 되어 데이터를 할당 할 수 있게 되는 것이다.

 

하지만 이렇게 하다보면 데이터 양이 많아질 때 데이터를 불러오는 동안 빈 화면이 보여지면

사용자 입장에서는 데이터를 불러오는건지, 원래 빈 화면인지 알 수 없을 것이라는 생각이 들었다.

 

데이터를 불러오는 중이라고 표시하는 방법을 알아보던 중 많이 쓰이고 데이터 관리에 효율적인 라이브러리를 사용하게 되었다.

react-query를 사용하는 것이다.

 

npm install react-query
 

먼저 react-query를 설치한다.

 

import { QueryClient, QueryClientProvider } from "react-query";
 
const queryClient = new QueryClient();
 

App.jsx파일에 QueryClient, QueryClientProvider를 불러온다.

  • QueryClient: 서버와 데이터 연결을 관리하고 캐시를 관리
  • QueryClientProvider: 모든 자녀 컴포넌트가 클라이언트를 사용할 수 있게 함

 

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <Main />
      </div>
    </QueryClientProvider>
  );
}
 
 

그리고 App 컴포넌트 안 최상단에 QueryClientProvider를 넣어주고 client로 QueryClient를 넣어주면 하위에 있는 모든 컴포넌트들에서 클라이언트가 가지고 있는 캐시와 기본 옵션을 사용할 수 있게 된다.

 

 

import { useQuery } from "react-query";
 

데이터를 불러올 컴포넌트로 이동하고 useQuery를 불러온다.

  • useQuery: 서버에서 데이터를 불러올 때 사용

 

const { data } = useQuery("posts", fetchPosts);
 

 

반환 객체에서 useQusery로 데이터 속성을 구조 분해한다. useQuery는 다양한 속성을 가진 객체 반환한다.

useQuery는 2개의 인자를 받는다.

 

  1. 첫번째 인자: 쿼리 키(쿼리 이름)
  2. 두번째 인자: 함수(쿼리에 대한 데이터를 가져오는 비동기 함수)

fetchPost는 API를 fetch하는 비동기 함수인데 여기서 데이터를 할당하면 map을 읽을 수 없다는 오류가 나온다.

useQuery에는 데이터가 정의되지 않으면 오류가 되게 두지 않고 적절한 조치를 취할 수 있는 속성이 있다.

 

 

const { data, isLoading } = useQuery("posts", fetchPosts);
 

 

  • isLoading: 데이터의 로딩 여부를 불린 값으로 알려줌
  • isError: 데이터를 가져올 때 오류 여부를 불린 값으로 알려줌

 

if (isLoading) return <h3>is Loading...</h3>;
 

빈 <div>를 반환하는 대신 로드 중인지 확인 가능하고 로딩중일 때 로딩 표시기로 조기 반환한다.

더이상 로딩하지 않으면 isLoading이 false가 되고 해당 게시물 제목과 페이지의 나머지 부분을 반환한다.

 

 

isFetching과 isLoading의 차이는 뭘까?

isFetching isLoading
비동기 쿼리가 해결되지 않음 isFetching의 하위 집합
fetching을 완료하지 않음 가져오는 상태에 있음
  쿼리 함수가 아직 해결되지 않음
  표시할 캐시된 데이터가 없음

아직은 큰 차이를 못느끼지만 Pagination을 할 때 캐시된 데이터가 있을 때와 없을 때를 구분해야 한다.