[Assignment 1] 하얀마인드 - Infinity scroll

이다은·2021년 7월 27일
1
post-thumbnail

🔗 Github

🔗 배포 링크

🔗 커밋 메시지 컨벤션 회의록


직접 구현한 부분 : ALL

팀원인 현정님과 Live share로 함께 진행하였습니다 😊


기능 구현 전 사전 셋팅

🔻 axios API 생성 및 데이터 불러오기

//* axios baseURL 생성
const axios = Axios.create({
  baseURL: "https://jsonplaceholder.typicode.com",
});

//* axios - GET
//* page, limit값에 따른 comments 불러오는 API 함수
export const commentsAPI = (page = 1, limit = 10) => {
  return axios.get(`/comments`, {
    params: {
      _page: page,
      _limit: limit,
    },
  });
};

🔻 styled-component UI css 구현

: styled-reset 을 설치해서, 브라우저 기본 css를 reset 해주었다.

import reset from "styled-reset";
import { createGlobalStyle, css } from "styled-components";

const globalStyle = css`
  ${reset};
  * {
    box-sizing: border-box;
  }
`;

const GlobalStyle = createGlobalStyle`
    ${globalStyle};
`;

export default GlobalStyle;

Hnet-image

🔻 Redux & Redux-Thunk 상태관리 및 비동기로 데이터 호출 기능구현

export const getCommentsThunk = () => async (dispatch, getState) => {
  dispatch(getComments());
  try {
    const currentPage = getState().comments.page;
    const { data } = await commentsAPI(currentPage);
    dispatch(getCommentsSuccess(data));
  } catch (error) {
    dispatch(getCommentsFailure(error));
  }
};

Infinity Scroll 방법(1)

🔻 Scroll event 활용

: scrollHeight, scrollTop, clientHeight 조건으로 bottom 여부를 확인한다.

  //* 화면 하단부까지 scroll되면, 새로운 comments 불러오기
  const _handleScroll = throttle(() => {
    const { scrollHeight, scrollTop, clientHeight } =
      document.documentElement || document.body;

    if (clientHeight + scrollTop === scrollHeight) {
      dispatch(getCommentsThunk());
    }
  }, 500);

  const handleScroll = useCallback(_handleScroll, [_handleScroll]);

  //* 마운트 시 scroll event 등록
  //* 언마운트 시 scroll event 등록
  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, [handleScroll]);

  //* 초기 렌더링 시, page=1 comment 불러오기
  useEffect(() => {
    dispatch(getCommentsThunk());
  }, [dispatch]);

: Throttle을 적용하여 스크롤 이벤트가 많이 발생하지 않도록 해주었다.

//* throttle 함수
const throttle = (func, delay) => {
  let timeout = null;
  return function (...args) {
    if (!timeout) {
      timeout = setTimeout(() => {
        func.call(this, ...args);
        timeout = null;
      }, delay);
    }
  };
};

Infinity Scroll 방법(2)

🔻 Intesection Observer를 활용

: Intesection Observer에 원하는 dom을 observe 시키고, isIntersecting일 경우 원하는 함수를 실행시키는 방법으로 구현했다.
: Intesection Observer IE에서 지원되지 않는다. 이 경우에 polyfill를 적용해주어야한다.

 //* Container div에 접근하기 위해 useRef 생성
  const fetchMoreTrigger = useRef(null);

  //* 화면에 Container div가 보일 경우, 새로운 comments 정보 불러오기
  const fetchMoreObserver = new IntersectionObserver(([{ isIntersecting }]) => {
    if (isIntersecting) {
      dispatch(getCommentsThunk());
    }
  });

  //* 마운트시 ref에 IntersectionObserver observe 적용
  //* 언마운트시 ref에 IntersectionObserver unobserve 적용
  useEffect(() => {
    fetchMoreObserver.observe(fetchMoreTrigger.current);
    return () => {
      fetchMoreObserver.unobserve(fetchMoreTrigger.current);
    };
  }, []);

  return <Container ref={fetchMoreTrigger}> FetchMore </Container>;
profile
단단_프로트엔드개발자!

0개의 댓글