초보 개발자의 성장 일기
데이터 fetch 후 map을 하면 읽을 수 없는 이유 본문
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개의 인자를 받는다.
- 첫번째 인자: 쿼리 키(쿼리 이름)
- 두번째 인자: 함수(쿼리에 대한 데이터를 가져오는 비동기 함수)
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을 할 때 캐시된 데이터가 있을 때와 없을 때를 구분해야 한다.
'Development > React JS' 카테고리의 다른 글
[React] 아이콘 사용시 라이브러리에서 SVG를 사용하게된 이유 (2) | 2024.03.07 |
---|---|
메뉴 hover시 border-bottom넣을 때 글자 움직임 (0) | 2024.01.23 |
로그인 입력폼이 유효하지 않을 때 (2) | 2024.01.09 |
Hooks 규칙 (0) | 2024.01.04 |
[React] 카카오맵 지도 라이브러리 사용방법 (1) | 2023.12.20 |