0511 TIL

김형석·2022년 5월 11일
1

wanted-POB

목록 보기
8/26

새로 배운것

InfiniteScroll

  • onScroll 이벤트
  • Intersection observer API

무한스크롤 구현시 onScroll

💡 scroll event를 보며 페이지가 끝에 오는지 판단하는 방법

Intersection Observer API

타겟과 viewport 사이의 intersection 변화를 비동기적으로 관찰하는 방법

  • LazyLoading
  • Infinite-scroll
  • 사용자 결과 여부에 따른 애니메이션

등에 사용됨

Intersection Observer API를 사용하는 이유

  1. Scroll Event를 사용해서 구현할 때 사용하는 debounce & throttle 을 사용하지 않아도 됩니다..
  2. Scroll Event를 사용해서 구현할 때 구하는 offsetTop 값을 구할 때 는 정확한 값을 구하기 위해서 매번 layout을 새로 그리는데 이를 Reflow라 합니다. Intersection Observer를 사용하면 Reflow를 하지 않습니다.
  3. Scroll Event를 사용하는것 보다 비교적 이해및 사용하기가 쉽습니다

useInView

react-intersection-observer 라이브러리

npm i react-intersection-observer

사용 방법

import React from "react"
import { useInView } from "react-intersection-observer"

const App = () => {
  const [ref, inView] = useInView()

  return (
    <div ref={ref}>
      Element {inView.toString()}
    </div>
  )
}

export default App

ref 를 div에 걸어주면 해당 요소가 보이면 inView가 true 로, 안 보이면 false로 자동으로 변경됩니다.

Infinite Scroll

import { useInView } from 'react-intersection-observer'

const [ref, inView] = useInView()


useEffect(() => {
    if (inView) setPageNumber((prev) => prev + 1)
  }, [inView])


searchMovieList.map((movie, idx) => (
   <React.Fragment key={movie.imdbID}>
     {searchMovieList.length - 1 === idx ? (
       <div ref={ref}>
          <MovieCard
             title={movie.title}
             year={movie.year}
             imdbID={movie.imdbID}
             type={movie.type}
             poster={movie.poster}
           />
        </div>
       ) : (
        <MovieCard
           title={movie.title}
           year={movie.year}
           imdbID={movie.imdbID}
           type={movie.type}
           poster={movie.poster}
        />
      )}
   </React.Fragment>
 ))

React fragments

Fragments - React

Git

git의 파일,폴더명의 대소문자 변경 추적

git config core.ignorecase false

설정 이후 커밋하기전에 아래 명령어 실행 후 하는것을 권장

git rm -r --cached .

lodash

npm install lodash
기업 과제로 준 api가 굉장히 별로라서,, 중복된 아이디를 가지고 있는 요소를 제거하기 위해 lodash의 uniqBy()를 사용하기 위해 설치했다

import * as _ from 'lodash'
 
const newList = _.uniqBy(arr, 'key')

key를 기준으로 arr의 요소들의 중복을 제거해준다.

회고

로직이 꼬인 작업이 하나 있었다

searchInput (index.tsx)

// pageNumber = recoil value
useEffect(() => {
    if (pageNumber !== 0) {
			//api 불러오는 함수
      callApi(searchWord, pageNumber)
    }
  }, [pageNumber])

//...

function callApi(word: string, page: number) {
    moviesApi.searchMovielist(word, page).then((res) => {
      const success = res.data.Response.toLowerCase()

      if (success !== 'false') {
        const totalResultCnt = Number(res.data.totalResults)
        const lastPage = Math.ceil(totalResultCnt / DATA_COUNT)

        setSearchList(res.data.Search)
        setAdditionalData({ totalResults: totalResultCnt, lastPageNumber: lastPage })
      } else {
        resetSeachList()
      }
    })
  }

search (index.tsx)


useEffect(() => {
    if (pageNumber !== FIRST_PAGE) {
      callMoreApiData(pageNumber)
    }
  }, [pageNumber])

// 무한 스크롤 (가장 마지막 엘리먼트 보고있을때 페이지 값 증가)
useEffect(() => {
    if (inView) setPageNumber((prev) => prev + 1)
  }, [inView])

//api 실행 함수
function callMoreApiData(page: number) {
    moviesApi.searchMovielist(currentWord, page).then((res) => {
      const dataList = res.data.Search
      if (dataList !== undefined) {
        setSearchMovieList((prev) => [...prev, ...dataList])
      }
    })
  }
  1. 검색창을 담당하는 searchInput에서 onSubmit시 pageNumber를 1로 set해준다
  2. pageNumber의 변화를 추적하도록하여 초기값(0)이 아닐시 api 실행
  3. 이후 스크롤이 최하단에 갈 경우 페이지 넘버 증가 시키고 페이지가 변화할때마다 api에서 데이터를 받아와서 set해준다

이 과정에서 의도된대로 동작이 안했던 이유가 1번의 조건을 제대로 안걸어줬기 때문에

3번 과정에서 pageNumber가 변환이 되니까 searchInput의 useEffect에서도 페이지 변화를 감지했고
if문에 들어가게되어 (0이 아니므로)

setSearchMovieList((prev) => [...prev, ...dataList])를 제대로 작성해줬음에도 불구하고 이전의 값들이 날아가게 되는 현상이 발생했던 것

📝해야할 일

  • 즐겨찾기 페이지
  • 모달 컴포넌트
  • 추가 데이터 확인해보기 (https://imdb-api.com/) imdbID 활용
profile
코드로 소통하기 위해 힘쓰는 프론트엔드 개발자 입니다.

0개의 댓글