react infinite scroll2

akanana·2023년 7월 4일
0

✔개요

react infinite scroll 라이브러리 사용중, 여러 에러를 겪은 후, custom infinite scroll 구현 및 사용

✔상세

이전 포스트에서 사용해본 방법을 통해 실제 프로젝트에 infinite scroll을 통한 페이지를 구현하였다. 하지만 실제 axios를 통해 받은 데이터 또는 props등으로 전달한 배열을 렌더링과정에서 많은 에러들이 발생하였고, 자세한 동작 과정들을 보고 수정하기 위해 직접 infinite scroll을 구현하였다.

우선 현재 프로젝트에서는 axios가 아닌
상위 페이지에서 axios로 가져온 journals=[]를 하위 페이지로 전달, infintie scroll에서 추가적인 렌더링을 할때에

✔구현

import useFetch from 'hook/useFetch';
import { useCallback, useEffect, useRef } from 'react';
import { useState } from 'react';

function MyJournals(props) {
  // 상위 페이지에서 받아온 journals 배열
  const { journals } = props; 
  // page
  const [page, setPage] = useState(0); 
  // 렌더링하기위한 데이터가 담긴 list를 useFetch로 가져옴
  const { list } = useFetch(journals, page); 

  // loader div의 dom 선택
  const loader = useRef(null);
  // page를 증가시키는 메소드
  const handleObserver = useCallback((entries) => {
    const target = entries[0];
    if (target.isIntersecting) {
      setPage((prev) => prev + 1);
    }
  }, []);
  // useEffect
  useEffect(() => {
    // 특정 객체를 볼시, handleObserver 실행
    const observer = new IntersectionObserver(handleObserver);
    if (loader.current) {
      observer.observe(loader.current);
    }
  }, [handleObserver]);

  let jsf = (
    <div className="box page my-journals">
      <div className="inf-scroll">
        {list.map((journal, i) => {
          let data = (
            <div className="my-journal" key={journal.journalPk}>
              {i}
              {journal.journalTitle}
            </div>
          );
          return data;
        })}
        <div className="loader" ref={loader} />
      </div>
    </div>
  );
  if (props.visi) {
    return jsf;
  } else {
    return;
  }
}

export default MyJournals;

useFetch

import { useState, useEffect, useCallback } from 'react';

function useFetch(journals, page) {
  const [list, setList] = useState([]);
  let jPerPage = 10;

  const sendQuery = useCallback(async () => {
    setTimeout(() => {
      try {
        // start, end Index 설정
        const startIndex = page * jPerPage;
        const endIndex =
          (page + 1) * jPerPage < journals.length ? (page + 1) * jPerPage : journals.length;
        let array = list;
        // journals 를 list에 추가
        // + jpa에서 order asec으로 들고온 데이터이기에 뒤에서부터 출력 필요
        for (let index = startIndex; index < endIndex; index++) {
          array.push(journals[journals.length - index - 1]);
        }
        setList(array);
      } catch (err) {}
    }, 500);
  }, [journals, page]);

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

  return { list };
}

export default useFetch;

✔후기

IntersectionObserver이란 메소드를 통해 추후 다른 기능을 구현 가능할것같다. 특히 위에서는 생략되었으나, IntersectionObserver의 옵션또한 확인 후 추가적으로 구현함이 좋아보인다.
useRef에 대한 사용법을 다시금 익혔다.
가장 많이 참고한 링크가 둘 있었다.
suyeonme velog와,
Dave Gray youtube
였는데, 유튜브 영상에서 hooksaxios등 일부 기능들을 모듈화를 깔끔히 진행한 코드를 보았다.
추후 해당 내용에 대한 지속적인 학습을 통해서 좀 더 깔끔하게 react 코드를 짤 수 있도록 노력해야겠다

0개의 댓글