Infinite Scroll

Brad·2021년 7월 27일
1

무한스크롤?

무한스크롤은 페이지네이션 기법을 응용하여 아래 혹은 위로 스크롤을 할 때, 계속해서 새로운 데이터를 받아오는 방법이다.

구현 과정

무한스크롤을 구현하려면 우선 나타낼 정보를 하나의 박스로 담아야한다. 그리고 그 박스들을 정렬해서 보일 페이지를 꾸민 후, mockup data를 통해 어느정도의 페이지를 구현해본다.
이러한 과정을 거친 후, mockup data가 아닌 실제 api를 받아오고, 이 정보가 박스에 제대로 그려지는지 확인한다.
마지막으로 페이지 혹은 html의 scroll height, scroll top, client height을 가져와 각각의 값을 비교하여 위치에 다다랐을 때 새로운 api를 받아온다.

  1. api 불러오기
import axios from "axios";
const apiUrl = "";

const instance = axios.create({
  baseURL: apiUrl,
});

export const getComments = async (page, limit) => {
  const response = await instance.get(
    `/comments?_page=${page}&_limit=${limit}`
  );
  return response.data;
};

axios library를 통해 GET 요청

  • baseURL과 나중에 사용될 수 있는 기본 header를 넣기 위해 axios.create() 함수를 통해 instance를 정의함.
  • instance.get() 파라미터에는 baseURL을 제외한 나머지 부분이 들어갈 수 있다.
  • return을 하되, getComment()는 try로 감싸져야한다.
  1. 불러온 api 추가하기
  const [comments, setComments] = useState([]);
  const [page, setPage] = useState(1);

  const loadComments = async (page) => {
    try {
      const temp = await getComments(page, 10);
      const tempComments = comments.concat(temp);
      setComments(tempComments);
    } catch (e) {
      console.error(e);
    }
  };

  useEffect(() => {
    loadComments(page);
  }, [page]);

page가 갱신될 때 마다 loadComments가 실행되며, 불러온 data는 temp에 담겨 comments와 이어붙인 후 comments로 초기화된다.

let timeInterver = '';

const scrollEvent = ()=>{
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollTop = document.documentElement.scrollTop;
    const clientHeight = document.documentElement.clientHeight;
    console.log(scrollTop)
    if (scrollTop + clientHeight >= scrollHeight - 950) {
      setPage(page + 1);
    }
  }
  
  const handleScroll = () => {
    clearTimeout(timeInterver);
    timeInterver = setTimeout(scrollEvent, 300)
  };

  
  useEffect(() => {
    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  });

window.addEventListener를 통해 scroll 감지

  • scrollTop(scroll 상단의 위치) + clientHeight(창의 길이) >= scrollHeight(content 총 길이) 일 때 page를 수정한다.
  • timeInterver : 이벤트를 계속해서 받아오면 성능의 저하가 있을 수 있기 때문에 event가 끝나고 300ms 이후 callback function이 실행된다.
  • 950을 뺀 이유 : 박스 1개의 높이는 대략 194px, margin을 생각하고 적당히 잡아 박스 4개의 높이를 950px로 계산했다. 어느 정도의 값을 빼지 않으면 스크롤이 최하단에 닿아야 새로운 data를 불러오고, 이렇게 되면 사용자 입장에서 불편한 점이 생길 수 있어 미리 불러오게끔 설정해놓았다.

Box 내부의 height

  • 가지고 오는 Comment의 길이가 제각각이기 때문에 Box내부의 요소 height를 하나씩 쌓아주고, 마지막 Comment body 부분은 auto, Box의 heighteh auto를 할당해서 그 크기에 맞게 변경되도록 했다.
  • 하지만 2줄 이하의 내용이 들어올 경우에는 min-height : 63px으로 3줄 만큼의 크기를 유지시켜 일관성이 유지되도록 했다.

What I learned..

처음 infinite scroll을 접했을 때 걱정이 앞섰다. 하지만 pagination을 기존에 구현해봤었고, scroll에 대한 정보를 받아오기만 하면 되는 구조를 파악하니 이해도 쉽고 구현도 어렵지 않았다.
scroll 관련 라이브러리를 활용하여 구현하고 싶었지만 이 부분은 학습이 더 필요할 것 같아서 정보가 많은 쪽으로 택했다. 또한 intersection Observer를 통해 구현하는 부분도 많았는데, 처음엔 이해가 안 되었지만 기본적인 방법으로 구현하고 나니 어떠한 동작으로 진행이 되는지 나중에 깨달았다.
다만 이 방법은 하단에 목표로 하는 target이 어디에 위치해있는지 알아야하기 때문에 스크롤이 하단에 닿기 전에 새로 불러오려고 하는 나의 목적과는 맞지 않는다고 생각한다.

profile
즐거운 개발자!

0개의 댓글