프론트엔드 데브코스 5기 TIL 24 - 무한 스크롤 UI, 코드리뷰

김영현·2023년 10월 30일
1

TIL

목록 보기
28/129

무한 스크롤 UI

모바일 환경에서 많이 사용한다. 따라서 모바일 환경이라 가정하고 한다.
개발자도구 누르면 모바일 화면으로 바꿀수있음!(크기나 기기 설정가능).

무한스크롤이란?

컨텐츠 마지막 요소 볼때쯤 다음 컨텐츠가 있으면 불러온다.
방식은 보통 2가지가 있음.

  • 윈도우 스크롤 이벤트: 화면 전체 높이와 스크롤 위치를 통해 스크롤이 컨텐츠 끝에 닿았는지 체크.
  • Intersection Observer API: 특정 컨텐츠에 옵저버를 등록해두면, 시야에서 벗어날때 쯤 알람이 옴.

포인트

데이터를 가져올때, 반복해서 가져오게 될 수 있다.
따라서 데이터를 가져올땐 이벤트 발생이 안되게 해야함.

  1. 쓰로틀을 이용한다(처음 이벤트만 받아주고 나머지는 무시)
  2. 불리언 하나 선언해서 이용(isLoading같은...)

또한, 마지막 데이터를 불러오는 체크를 해주어야함(총 데이터 길이 체크)

윈도우 스크롤 이벤트 기반

윈도우 스크롤 이벤트는 이렇게 구한다.

 window.innerHeight + window.scrollY + 보정값 >= document.body.offsetHeight
  • window.innerHeight: 창 틀을 뺀 내부 크기(북마크바, 툴바 등 제외)
  • window.scrollY: 문서를 아래로 얼마나 스크롤 했는지!(가만히있을땐 0이니까, window.innerHeight를 더해줘야 한다.
  • document.body.offsetHeight: 문서의 높이


    정확히는 margin을 제외한 높이

따라서 위의 수식뜻은 스크롤 하다 문서의 끝에 닿으면?이다.

Intersection Observer API 기반

IE최신버전이 아니면 지원안함. (근데 아직도 ie쓰는사람이 있나...???)
이미지 지연 로딩 기능도 쉽게 구현 가능하다.

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting && !this.state.isLoading) {
          alert("스크롤 끝", entry);
        }
      });
    },
    {
      // root: null, 요소를 감시할 상위 요소(기준요소를 정하는거구나! 뷰포트가 디폴트다)
      // rootMargin: 0, 기준 요소보다 더 크게 설정가능(감시 margin)
      threshold: 0, //요소가 얼만큼 보였는지? 0이면 대상 뷰포트 닿자마자, 1이면 모두 보이고나서
    }
  );

observe로 관찰자를 설정하고 unobserve로 관찰자를 뺀다

    if ($nextLi) {
      if ($lastLi) {
        observer.unobserve($lastLi);
      }
      $lastLi = $nextLi;
      observer.observe($lastLi);
    }

느낀점

오늘파트는 쉬웠지만 실무에 굉장히 많은 도움이 될것 같다.
또한 한 가지 답은 없고 상황마다 적절히 사용하는 게 좋아보인다. 이상!


코드 리뷰

엉망진창 코드를 감사하게도 세세하게 읽고 리뷰를 남겨주셨다!
일단 궁금해서 물어봤던 목록부터 체크하고 넘어가겠다.

궁금했던 점들

Q : contenteditable로만든 에디터의 커서, 자-모음분리 관련 해결법
A : 에디터는 복잡하기에 보통 라이브러리 사용. 아니라면 selection객체 활용, 자모음 분리는 intl.Collator를 사용하기도 함.
정리:selection객체는 현재 커서의 위치. Intl.Collator는 정렬 및 비교를 주어진 로케일(지역)에 따라 해줌.
음...selection까지는 알겠는데, Intl.Collator로 어떻게 자-모음분리를 처리하는지는 모르겠다.
일단 킵!

Q : POST, PUT등으로 서버의 데이터를 업데이트하면, 전역스토어가 이를 감지하고 데이터를 다시 fetching하여 사용하면 각 컴포넌트마다 props drilling과 상태관리가 편해질 것 같은데, 맞는 방법일까요?
A : 서버데이터를 업데이트한뒤, 다시 fetch 하여 데이터를 받아와야합니다.
전역스토어가 업데이트를 감지하여 다시 fetch 하지 않습니다.
스토어는 데이터의 보관함 역할만 할뿐입니다.
정리 : 이건 나의 무지에서 나온 질문...스토어자체는 보관기능만 하고, refetch요청은 결국 컴포넌트에서 처리해야함.

Q : DocumentList와 DocumentItem을 이용하여 재귀적 렌더링을 하였는데, 다른사람이 보았을때 단박에 이해하기 어려운 구조인 것 같습니다. 어떤 구조가 더 적절할까요?
A : 재귀적인 렌더링은 적절해보입니다.
다만 컴포넌트내부에서 많은 역할을 하고 있는것이 코드 가독성에 문제가 되고있습니다.
컴포넌트는 view만 담당하고, 데이터의 보관, 변경하는 레이어의 분리, 함수의 분리 등이 필요해보입니다.
(일주일이상 작업하셨고, 프로젝트가 거대해보이실텐데요. 지금 리팩토링하기엔 설계를 처음부터 뜯어고쳐야할수있습니다. 지금은 고민을 해보시고, 다음 프로젝트부터 조금씩 적용해보시 괜찮습니다. 새로운 학습과 과제를 진행하며 이 작업을 하기에는 시간이 부족할것입니다. )
정리 : presenter-container패턴을 사용해도 될 것 같고, 어차피 전역 스토어기능도 넣으려고 했으니 함 도전해보자~

Q : 문서를 클릭하면, 문서 메뉴가 하이라이트 되게 만들었습니다. documentlist에서 렌더가 완료되었을때 호출하고(초기렌더링, 새로고침시), window에 이벤트리스너popstate, route-change(커스텀이벤트)를 등록하여 뒤로가기,앞으로가기,주소입력 을 처리하였습니다
괜찮은 방법인지 궁금합니다
A : 이 모든 행위들은 url이 변한다는 공통점이 있습니다.
url의 변화를 감지하면 더 간단하게 문서 메뉴의 하이라이팅을 구현할수있어보입니다.
정리 : 찾아보아도, 한번에 Url변화를 감지하는 기능은 없다. 따라서 모아놓고 추상화하여 사용하라는 말씀이신 것 같다. 이렇게 해보고 다시 여쭤봐야지!

Q : 변수와 함수명이 제일 어렵습니다...ㅠㅠchangeBackgroundSelectedDocument처럼 함수명이 길어지면 어떻게 처리하시나요?
A : 함수명이 길어진다는것은 너무많은 행위를 하고있다는말일수도 있습니다.
함수내부 코드의 역할을 쪼개보세요.
그게 아니라 단어길이의 문제라면, 변수명에 쓰인 여러 단어의 조합을 의미하는 하나의 단어를 찾아내보세요.
원래 이게 젤 어렵습니다,,
정리 : 원래 어렵구나...가 아니라. 확실히 너무 많은 행위를 넣었을 수도있다. 이 부분을 최대한 자각하며 단어도 찾아보고 해야지!

Q : svg파일 관리는 어떻게 하는가?
A : js파일 svg파일 둘다 상관없다
정리 : js파일이 조금더 편했다.

Q : 버튼상태를 로컬스토리지에 저장하는데, { key: dataset.id, value: { isFoleded : boolean }} vs { key: isFolded, value:{ 1:false,2:false, 3:true} } 이런식으로 밸류에 datasetid : boolean 형식으로 저장하는게 좋을까요? 어떤방법이 좋은지 궁금합니다!
A : 프로젝트마다 다를것입니다.
첫번째 방법은 id가 한정된 프로젝트에서 편리할거구요. 다만 Key가 2000만개면 문제가 생길수잇겟죠?
두번째 방법은 여러 버튼이 존재할때 쉽게 모든 데이터를 가져올수있겠습니다.
유리한걸 선택하면 됩니다. 무조건 좋은건없습니다.
정리 : 항상 무조건 좋은건 없다! 이말은 항상 명심하자. 이번 과제는 노션 클론이니 문서의 갯수는 최대 몇백개일 것이다. 따라서지 첫번째 방법(사용하고있던 방법)이 좋아보인다.

Q : 재사용 가능한 컴포넌트는 최대한 의존성을 없애고 쪼개고, 조금 달라지는 컴포넌트면 상속해서 새로 제작하는게 좋을까요?
A : 좋은 질문이네요.
삼각형, 파란색이 칠해진 삼각형, 한쪽 변이 파란색인 삼각형, 모든꼭지점에 작은동그라미가 달린 삼각형, 무지개빛깔 삼각형등 여러 요구사항, 아주 조금 달라지는 변경 등이 있을수있겠죠.
상속을통해 해결할수도있겠지만, 섣부른 추상화는 시간이 지날수록 너무많은 분기처리가 생길수도있는 노릇입니다.
상황에 맞게 개발자가 선택해야할 문제라고 생각합니다.
정리 : 이것도 상황에 맞게 따른 것 맞다. 또한 섣부른 추상화는 너무 많은 분기처리가 생길 수 있다.

코드 리뷰

는...오늘까지 팀원 코드를 리뷰해야하는 관계로, 내일 하겠다!

profile
모르는 것을 모른다고 하기

0개의 댓글