[TIL] 무한 스크롤 도전기

·2024년 1월 17일
1

TIL

목록 보기
75/85
post-thumbnail

일단 무한스크롤을 구현하려면 스크롤이 특정 부분에 닿았을 때 특정 함수를 실행하기 위해
react-intersection-observer 와 같은 라이브러리를 설치하자.

yarn add react-intersection-observer

intersection-observer 에 대한 설명은 블로그 참고-⭐️

👉 https://heropy.blog/2019/10/27/intersection-observer/

장소 검색 페이지 부분을 무한스크롤로 구현해야 하는데,,
처음에 리액트 쿼리의 useInfiniteQuery 를 사용하여 구현해보려 하였으나 실패.

왜나하면 우리는 약 12000개의 장소 정보가 supabase의 places 테이블에 저장되어 있어서
useInfiniteQuery의 getNextPageParam 함수 부분을 작성하는게 난감했다.

const { data, error } = await supabase
        .from('places')
        .select('*')
        .ilike('place_name', `%${searchValue}%`)
        .range((currentPage - 1) * pageSize, currentPage * pageSize - 1);

이런식으로 range 메서드를 통해 pageSize 만큼 끊어서 가져올건데,
이를 통해 반환되는 data에는 total_page 라던가, lastPage 와 같은 정보가 들어있지 않다.

그래서 useInfiniteQuery 사용을 포기하고
다른 방식으로 구현해보려고 시도했다.

  useEffect(() => {
    // 새로운 검색어가 입력될 때 기존에 검색된 장소를 비움
    setSearchedPlaces([]);
    setCurrentPage(1);
  }, [searchValue]);

  const loadMoreData = async () => {
    setLoading(true);
    try {
      const { data, error } = await supabase
        .from('places')
        .select('*')
        .ilike('place_name', `%${searchValue}%`)
        .range((currentPage - 1) * pageSize, currentPage * pageSize - 1);
      if (error) {
        console.error('데이터 가져오기 에러:', error.message);
      } else {
        if (data.length === 0) {
          return;
        }
        console.log('페이징 및 필터링된 데이터:', data);
        setSearchedPlaces([...searchedPlaces, ...data]); // 기존 데이터와 새로운 데이터 병합
        setCurrentPage((prev) => prev + 1); // 다음 페이지로 이동
      }
    } finally {
      setLoading(false);
    }
  };

더 리팩토링을 할거지만, loadMoreData 라는 함수를 다음과 같이 작성하였다.
그리고

const { ref } = useInView({
    threshold: 1,
    onChange: (inView) => {
      if (!inView) return;
      loadMoreData();
    },
  });

이 부분을 추가하여 무한스크롤을 구현해보았다.

	  <div
        style={{
          textAlign: 'center',
          backgroundColor: 'green',
          color: 'white',
          width: '100%',
          height: 50,
        }}
        ref={ref}
      >
        Trigger to Fetch Here
      </div>

Trigger to Fetch Here 부분에 닿으면 새로운 데이터 20개를 가져온다.
아직 수정해야 할 부분이 많지만......
오늘 처음 무한스크롤에 도전해보고 성공했다는 것에 의의를 둔다..
아직 UI는 못생긴 상태ㅎㅎ
갈길이 멀다!!! 🏃‍♀️🏃‍♂️

profile
느리더라도 조금씩, 꾸준히

0개의 댓글