Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

kohigowild

파이어베이스로 무한 스크롤 구현하기 본문

mitmitwiki

파이어베이스로 무한 스크롤 구현하기

kohi ☕ 2023. 4. 8. 02:00
🌼 페이지 진입 시 불러올 첫 번째 쿼리문 작성
export const getExploreDoc = async (setKey: any) => {
  const fristQ = query(collection(db, 'feed'), orderBy('createAt', 'desc'), limit(4));
  const querySnapshot = await getDocs(fristQ);
  const data = querySnapshot.docs.map((doc) => ({
    ...doc.data(),
  }));
  setKey(querySnapshot.docs[querySnapshot.docs.length - 1]);
  return data;
};
  • limit : 4개의 게시물을 불러온다.
  • 불러온 데이터 중 가장 마지막 값을 setKey에 저장한다.

 

🌼 이벤트가 있을 때마다 불러올 쿼리문 작성
export const getMoreExploreDoc = async (key: any, setKey: any) => {
  const moreQ = query(collection(db, 'feed'), orderBy('createAt', 'desc'), startAfter(key), limit(4));
  const querySnapshot = await getDocs(moreQ);
  const data = querySnapshot.docs.map((doc) => ({
    ...doc.data(),
  }));
  setKey(querySnapshot.docs[querySnapshot.docs.length - 1]);
  return data;
};
  • startAfter : key의 다음 값부터 불러온다. key를 포함하는 경우 startAt 메서드를 사용한다.
  • 데이터를 불러온 이후 setKey를 통해 key를 업데이트 한다.

 

데이터를 잘 불러오는지 테스트를 위해 test 버튼에 onClick 이벤트로 getMoreExploreDoc을 걸어 주었다.

잘 불러온다. 이제 무한 스크롤을 구현해 보자!

 

🌼 Intersection Observer API 설치 및 적용

 

yarn add react-intersection-observer

 

const [isLast, setIsLast] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
const [ref, inView] = useInView();

const getMoreQ = async () => {
    try {
      setLoading(true);
      const result: any = await getMoreExploreDoc(key, setKey);
      setFeedList([...feedList, ...result]);
      setLoading(false);
      {
        !result.length && setIsLast(true);
      }
    } catch (error) {
      console.log(error);
    }
  };

useEffect(() => {
    if (!key) return;

    if (inView && !loading) {
      getMoreQ();
    }
  }, [inView]);

return (
    <Center>
      <Box padding="2vh 0">
        {feedList.map((card, index) => (
          <FeedCard card={card} comment={true} key={index} />
        ))}
        <Center>
          {!isLast && !loading && (
            <Spinner ref={ref} thickness="4px" speed="0.65s" emptyColor="gray.200" color="green.400" size="xl" />
          )}
        </Center>
        <Center>
          {isLast && (
            <Alert status="success" mt="16px">
              <AlertIcon />
              마지막 피드입니다.
            </Alert>
          )}
        </Center>
      </Box>
    </Center>
  );
  • 로딩 스피너를 Observer 객체로 지정하고 스피너가 화면에 보이면 getMoreQ를 실행한다.
  • getMoreExploreDoc으로부터 받아오는 데이터가 빈 배열인 경우 isLast를 true로 업데이트한다.