[6일차] 무한스크롤 2편

h-a-n-a·2023년 8월 12일

💫Ed Sheeran

목록 보기
6/24

어제 만들었던 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 배형진

profile
하루하루가 연습이니 내일은 더 강해질 겁니다

0개의 댓글