[TIL] 내일배움캠프 React 과정 2024.05.03

김형빈·2024년 5월 3일
0

내일배움캠프

목록 보기
13/81
post-custom-banner

오늘의 한 일

  • 코딩테스트 연습
  • 팀 프로젝트
    • scroll out 라이브러리 적용
    • 무한 스크롤
    • 코드 리팩토링

오늘의 기능 구현

1. scrollOut 라이브러리를 활용한 fade in, out 효과

scrollOut이란?

  • scroll 변화를 감지해 css 효과를 줄 수 있는 라이브러리

  • 그냥 내렸을 때보다 영화 포스터가 생성되는 듯한 느낌을 준다

코드

  • html
<script src="https://unpkg.com/scroll-out/dist/scroll-out.min.js"></script>
  • css
.movie {
  display: flex;
  flex-direction: column;
  align-items: center;

  gap: 40px;

  border-radius: 5px;
  color: white;
  font-weight: bold;
  cursor: pointer;

  /* 투명도 추가 */
  opacity: 0;
  transition: opacity .35s 
}

.movie[data-scroll='in']{
  opacity: 1;
  transition-duration: 1s;
}
  • javascript
ScrollOut({
        targets: ".movie",
        once: true,
      });
주의점: target의 태그가 비동기로 생성되는 경우, 해당 비동기 함수안에 선언해야 함!

문제 발생

  • img 태그에서 onerror만 설정해주었는데 애니메이션이 실행된 후에 이미지가 삽입되어 어색하게 화면에 표시되었다

문제 해결

  • img 태그 src 속성에 삼항연산자로 조건을 추가하였다
<img src="${poster_path? moviePosterPath: 'icons/replaceMovie.png'}" onerror="this.onerror=null; this.src='icons/replaceMovie.png';">

2. 무한 스크롤 구현

처음 생각한 방법

const currentScroll = window.scrollY;
const windowHeight = window.innerHeight;
const bodyHeight = document.body.clientHeight;
if(currentScroll + windowHeight <= bodyHeight){
	//api호출
}
  • 그러나 스크롤을 할 때마다 이벤트가 발생한다는 문제가 있다
    • 짧은 시간 내에 수 백, 수 천의 이벤트가 동기적으로 실행될 수 있음
    • 계속해서 reflow를 발생시킬 수 있음
  • 최적화가 필요하다

Intersection Observer API

const options = {
  root: null, // 뷰포트를 기준으로 타켓의 가시성 검사
  rootMargin: "200px", // 확장 또는 축소 X
  threshold: 0, // 타켓의 가시성 0%일 때 옵저버 실행
};

function onIntersect(entries, observer) {
  const url = `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=ko-KR&query=${word}&page=${page}`;
  entries.forEach(async (entry) => {
    if (entry.isIntersecting) {
      page++;
      const data = await fetchGetData(url);
      const movies = data.results;

      //탈출 조건
      if (movies.length < 1) {
        observer.unobserve($listEnd);
        return;
      }

      //영화 카드 구현
      $movieContainer.insertAdjacentHTML(
        "beforeend",
        movies.map((movieInfo) => makeMovieCard(movieInfo)).join("")
      );

      //scroll시 fadeIn 애니메이션
      ScrollOut({
        targets: ".movie",
        once: true,
      });
    }
  });
}

const observer = new IntersectionObserver(onIntersect, options);
observer.observe($listEnd);
  • 스크롤 이벤트와 다르게 교차 시 비동기적으로 실행
  • reflow를 발생시키지 않음
  • 타겟 요소의 관찰이 시작되거나, 가시성에 변화가 감지되면 (threshold와 만나면) 등록된 callback(onIntersect)이 실행된다
  • Intersection Observer API의 한계
    • 중간에 스크롤을 멈췄는지 확인할 방법이 없음 -> 다시 스크롤 이벤트로 구현 필요
    • 광고 요금 청구 등에는 부적합하다
    • 하지만 이번 프로젝트에는 적절한 기술로 생각된다

오늘의 회고

하루 종일 코드 구현만 하느라 눈이 아프다... 어제의 다짐과 다르게 점점 의욕이 떨어지는 느낌이 든다. 스크롤 이벤트를 구현할 때는 찾아보고 위에서 정리한 것처럼 이유를 찾기는 했으나 오늘 정리한 정도의 이유면 충분한가?라는 고민도 아직은 해결되지 않는다. 또 프로젝트의 완성도를 높이기 위해 scrollOut 라이브러리를 사용해서 애니메이션을 구현하였지만 이 역시 이 프로젝트에 완성도를 높인걸까?라는 고민이 든다. 분명 많은 걸 배웠던 것 같은데 아직도 모르는 거 투성인 프론트엔드이다...
이번 주말과 휴일동안은 팀원분이 아이디어로 주신 정렬 버튼, 한글,영어 전환 버튼을 구현해보려 한다. 튜터님들이 말씀해주신데로 이번 프로젝트는 기초를 즐길 수 있을 떄 즐기자. 4개월이 짧다면 짧지만 길다면 긴 기간인 만큼 너무 급하게 가지말고 체력을 잘 배분하면서 진행할 수 있도록!
profile
The secret of getting ahead is getting started.
post-custom-banner

0개의 댓글