어제 만들었던 usePhotos 훅을 이용해 Photo 컴포넌트를 만들었다.
usePhotos에서 리턴했던 값을 토대로 사진 데이터를 가져오고 로딩 및 에러 상태를 관리했다.
import { PhotoContainer, PhotoInner, PhotoWrapper } from './style';
import { useEffect, useState, useRef, useCallback } from 'react';
import { getPhotosPage } from '@src/api/axios';
import usePhotos from '@src/hooks/usePhotos';
import EdImg from '../EdImg';
import Skeleton from '@mui/material/Skeleton';
function Photo() {
const [pageNum, setPageNum] = useState<number>(1);
//페이지 번호와 관련된 상태들 설정
const { isLoading, isError, error, results, hasNextPage } =
usePhotos(pageNum);
// usePhotos에서 반환했던 상태들 가져다가 사진데이터, 로딩/에러상태, 다음페이지여부 상태 관리하기
const intObserver = useRef<IntersectionObserver | null>(null);
// IntersectionObserver를 사용하여 lazy loading 구현하기 위한 Ref 설정
// 마지막 이미지를 관찰하고, 다음 페이지를 요청하는 함수 생성
const lastImgRef = useCallback(
(image: HTMLElement | null) => {
if (isLoading) return;
if (intObserver.current) intObserver.current.disconnect();
intObserver.current = new IntersectionObserver((images) => {
if (images[0].isIntersecting && hasNextPage) {
setPageNum((prev) => prev + 1);
}
});
if (image) intObserver.current.observe(image);
},
[isLoading, hasNextPage]
);
const content = results.map((image, i) => {
if (results.length === i + 1) {
return <EdImg ref={lastImgRef} key={i} image={image} />;
}
return <EdImg key={i} image={image} />;
});
useEffect(() => {
getPhotosPage();
}, []);
return (
<PhotoContainer>
<PhotoInner>
<PhotoWrapper>
{content}
{isLoading && <Skeleton />}
</PhotoWrapper>
</PhotoInner>
</PhotoContainer>
);
}
export default Photo;

오늘의 일기: 확실히 학원에서 내주는 과제 억지로 할 때보다 오천삼십배 더 재밌다...
되게 어려워보였는데 차근차근 공부하다 보니까 벌써 6일째 꾸준히 하고 있는 내 자신... 히ㅣㅎ ㅣ히 오늘은 내 자신에게 칭찬 한마디 해줘야지~~

참고사이트:
실전 Infinite Scroll with React by 배형진