데이터를 가져온 뒤 옵셔널 체이닝과 null 병합 연산자
by 담담이담import { useQuery } from "@tanstack/react-query";
import Post from "./Post";
import styles from "./PostList.module.css";
import { getPosts } from "../api";
function PostList() {
const { data: postsData } = useQuery({
queryKey: ["posts"],
queryFn: getPosts,
});
const posts = postsData?.results ?? [];
return (
<div className={styles.postList}>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</div>
);
}
export default PostList;
import Card from './Card';
import ContentInfo from './ContentInfo';
import styles from './Post.module.css';
function Post({ post }) {
return (
<Card className={styles.post}>
<div className={styles.content}>
<ContentInfo user={post.user} updatedTime={post.updatedAt} />
<p className={styles.description}>{post.content}</p>
</div>
</Card>
);
}
export default Post;
맨날 모르겠던 그거.. 대체 언제 옵셔널 체이닝과 null 병합 연산자를 사용해서 예외처리를 해주는 거지?
여기서 useQuery의 결과 값은 다음과 같다.
이를 {data : postsData}로 받았다는 건 이 결과값의 data 프로퍼티 이름을 가진 값을 구조분해해서 사용하겠다는 것이다.
또한 :postsData라고 씀으로써 구조분해와 동시에 이름을 변경해주었다.
우리가 원하는 건 postsData.results이다.
그래서 코드를 const posts = postData.results라고 접근할 수도 있지만, 저렇게 방어적으로 코드를 작성하는 이유는 다음과 같다.
만약 데이터를 불러와서 postData가 null이나 undefined라면 results라는 프로퍼티에 접근했을 때 에러가 발생할 것이다.
그래서 옵셔널 체이닝을 이용해 postData?.results로 접근한다.
또한 postData?.results의 값이 null이나 undefined라면 map 메소드로 접근하고자 할 때 배열이 아니기 때문에 .map으로 접근할 수 없어 다음과 같은 에러가 발생한다.
따라서 results가 null이나 undefined라면 빈배열로 초기화해준다.
빈배열로 초기화해주면 에러가 나지 않고, map에서 아무것도 리턴되지 않는다.
+ map을 여러번 돌릴 경우에 발생할 수 있는 에러
const linksData = data ? data.map(formatLinkRawData).map(mapLinksData) : [];
// const linksData = data?.map(formatLinkRawData).map(mapLinksData) ?? [];
아래 주석 처리한 코드처럼 작성했더니 또 TypeError: data.map is not a function라는 에러가 났다..
하 ㅠ 결론은 data?map(formatLinkRawData)를 해주면 data가 첫 렌더링 시 data가 null 일 때 data?map(formatLinkRawData)의 반환값이 undefined인데 거기서 또 map을 돌리려고 하니 나는 에러이다..
위처럼 조건부 렌더링으로 작성해주면 해결된다.
왜냐면 애초에 data가 있어야 map을 돌고 데이터가 있을 때 그 map을 돈 결과는 당연히 배열일 것이기 때문이다.
'React' 카테고리의 다른 글
리액트와 자바스크립트에서의 =, :의 모든 것 (2) | 2024.01.10 |
---|---|
useEffect의 실행 시점과 클린업 함수의 실행 시점 (1) | 2024.01.08 |
React.memo, useCallback, useMemo 차이 (0) | 2024.01.06 |
React : 데이터 로딩 및 에러 처리하기 (1) | 2023.10.24 |
React : 사이드 이펙트와 useEffect (0) | 2023.10.24 |
블로그의 정보
유명한 담벼락
담담이담