TIL. infinity scroll

FE_JACOB 👨🏻‍💻·2021년 7월 17일
0

Today I learned

목록 보기
7/30

Today I learn

infinity scroll with tabs

저번 게시글에 이어 infinity scroll에 대해 작성해보려고 한다.

내가 원했던 무한스크롤은 특정 박스 안에서 계속 무한스크롤이 생겨야하고 전체 위치는 100vh로 고정이 되어있어야했다. 그래서 스크롤을 해도 전체 높이는 변하지않으면서 박스안에만 스크롤이 생겨야했다.

내가 프로젝트할때 참고했던 왓챠피디아는 애초에 스크롤을 하면 그 박스안에서 무한스크롤이 구현되는게 아닌 화면 전체의 무한스크롤이었다. 그래서 스크롤을 하면 컨텐츠들이 올라가면서 진짜 overflow: hidden or scroll 되는게 아닌 div box로 그 위쪽을 덮어서 실제로는 안보이지만 그 밑으로는 없어지지않았다.

사실 그렇게 구현해도 보이는데 문제는 없었지만 개인적으로 제대로 구현해보고싶었다.
그래서 전체 height를 주고 그 박스 안에서만 scroll이 되도록 css를 만들었고 스크롤이 바닥에 닿으면 내가 누른 탭을 그대로 queryString으로 넣어줘서 fetch요청을 해왔다.
물론 백엔드와 offset과 limit를 잘 상의해서 결정했고 데이터가 많지않아서 5개씩 요청했다.

또한 더 보내줄 데이터가 없을시 계속 무한스크롤이 되게끔 맨 처음부터 데이터를 다시 보내주는 식으로 로직을 구성했다.

마지막으로 바로바로 로딩이 되는게 아니라 조금만 간격을 줘서 fetch가 되고있다는것을 보여주고 싶어서 setTimeout을 1000ms줬다.

// ## SCROLL이 바닥에 닿았을때 무한스크롤 함수
  handleScroll = e => {
    const { scrollTop, clientHeight, scrollHeight } = e.target;
    const { count } = this.state;
    const query = `limit=${LIMIT}&offset=${count + 1}`;

    if (scrollTop !== 0 && scrollTop + clientHeight >= scrollHeight) {
      // 몇번 스크롤이 바닥에 닿았는지 알아야 그에 맞는 데이터를 보내주기 때문에 count를 만들어서 사용했다.
      this.setState({
        count: count + 1,
      });
      setTimeout(() => {
        fetch(
          `${privateAPIKEY}?category=${
            this.state.tabLists[this.state.toggleStateNum]
          }&${query}`,
          {
            headers: {
              Authorization: localStorage.getItem('token'),
            },
          }
        )
          .then(res => res.json())
          .then(res => {
          //데이터가 5개만 보이도록 하는게 아닌 앞에서부터 쌓이게 해줘야한다.
            this.setState({
              contents: [...this.state.contents, ...res.results],
            });
          });
      }, 1000);
    }
  };

임의로 count 를 줬고 다른 탭을 누를때는 count가 0으로 다시 시작하게끔 로직을 구성했다.

이번 무한스크롤에서 헷갈렸던점은 스크롤이 바닥에 두세번 닿고 다른탭을 클릭했을때 그 탭에서는 fetch를 5개만해서 보여줘야하는데 비동기화 때문에 count가 0으로 바뀌기전에 fetch를 해서 15개 20개가 보이게 되는 상황이 발생했다.
그래서 scrollTop !== 0 이 될때의 조건을 하나더 입력해서 다른탭으로 갔을때 scrollTop은 당연히 0이니 그때는 fetch하지말라는 로직을 구성했다.

마지막으로 로딩중...을 만들고 싶었는데 애초에 content목록을 li만 map돌려서 스크롤되는 박스안에 로딩중을 넣고 그게 없어질때 스크롤이 바닥에 한번더 닿게 되면서 두번 fetch해왔다.
즉, 내가 한번 스크롤하면 두번 fetch하는 경우가 발생했다.
이 부분은 내가 다시 로직을 구성해서 구현할 예정이다.
그래도 좋은 경험이었다! 다 내 재산이다 ! ㅎㅎ

profile
단순히 개발자로서 제게 있었던 일을 적는 공간입니다 ✍🏻

0개의 댓글