Intersection Observer API를 사용한 무한 스크롤

7999 단어
우리는 일상 생활에서 많은 인터넷 기반 플랫폼과 상호 작용합니다. 우리는 여러 소셜 미디어 플랫폼과 쇼핑 사이트를 사용합니다. 온라인 쇼핑 플랫폼을 통해 쉽게 쇼핑할 수 있습니다. 위아래로 스크롤하여 제품이나 뉴스 피드를 봅니다. 아래로 내려갈 때 새로운 제품 세트 또는 뉴스 피드가 자동으로 로드됩니다.
무한 스크롤은 다음 gif에 표시됩니다.

시간을 낭비하지 않고 이제 본론으로 들어갑니다. 위의 UI를 스크롤하는 동안 새 제품 세트를 로드하는 것에 대해 논의했습니다. 새로운 제품 세트를 로드하는 것을 데이터의 페이지 매김이라고 합니다.

페이지 매김:- 페이지 매김은 연결되어 있고 유사한 콘텐츠가 있는 일련의 페이지입니다.

페이지 매김은 여러 가지 방법으로 수행할 수 있습니다. 페이지 매김은 href 속성이 있는 앵커 태그를 사용하여 페이지 하단 또는 상단의 내비게이션 바에서 수행할 수 있습니다. 나는 그것에 깊이 들어가지 않을 것입니다.
이 글은 react에서 "Intersection Observer API"를 사용하여 어떻게 무한 스크롤을 해야 하는지에 대한 내용입니다. "Intersection Observer API"를 사용하여 반응에서 어떻게 페이지 매김을 할 수 있습니까?
시작하기 전에, 나는 당신이 javascript, react, react hooks 및 Intersection observer API에 익숙하다고 가정합니다. Intersection observer API에 익숙하지 않은 경우 먼저 Intersection Observer API을 살펴보십시오.

지금 시작하자!!!.

이 기사에서는 주제의 데모를 위해 Github API를 사용하고 있습니다. 사용자의 저장소를 가져와 화면에 표시합니다.



먼저 반응 앱을 만들고 InfiniteScrolling 반응 기능 구성 요소를 만들었습니다.
이제 함수에서 repoData, totalRepos, currentPage 상태를 만들었습니다.

function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  function fetchData() {
    (async () => {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response => response.json());

      if (currentPage < totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() => {
    (async () => {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response => response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    <div className="App">
      {repoData.map((repo, index) => {
      return <h1 className="repo" key={repo.name + index}>{repo.name}</h1>
    })}
    </div>
  );

}

FetchData() 함수가 주어진 URI에서 데이터를 가져오고 상태로 설정합니다. makeRepoElem() 함수는 h1 요소의 배열을 생성합니다. 그리고 리포지토리 이름 목록이 페이지에 렌더링됩니다.



리포지토리의 외관을 좋게 하기 위해 몇 가지 스타일을 추가했습니다.

function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  const callBack = useCallback((node) => {

    if (node) console.log(node);
  })

  function fetchData() {
    (async () => {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response => response.json());

      if (currentPage < totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() => {
    (async () => {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response => response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    <div className="App">
      {repoData.map((repo, index) => {
      return <h1 className="repo" key={repo.name + index}>{repo.name}</h1>
    })}
    </div>
  );

}


이제 useCallback를 사용하고 그 안에 함수를 저장합니다. 그리고 이useCallback를 맵의 마지막h1 요소에 참조합니다. 마지막 요소가 생성되면 useCallback에 저장된 함수가 호출됩니다.



이제 문제는 Intersection observer API를 어디에 사용할 것인가입니다. 우리는 다음 단계를 따를 것입니다...
1- 새로운 옵저버 즉 const observer = new IntersectionObserver(callback, options)를 생성합니다.
2- 우리는 이 옵저버 즉 h1로 마지막 observer.observe(lastElement) 요소를 관찰할 것입니다.

마지막h1 요소가 뷰포트에 나타날 때마다 콜백이 호출됩니다.

function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  const observer = useRef();
  const callBack = useCallback((node) => {
    if (observer.current) observer.current.disconnect();

    observer.current = new IntersectionObserver(argus => {
      if (argus[0].isIntersecting) {
        if (currentPage < totalRepos / 30) {
          fetchData();
        }
      }
    })
    if (node) observer.current.observe(node);
  });

  function fetchData() {
    (async () => {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response => response.json());

      if (currentPage < totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() => {
    (async () => {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response => response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    <div className="App">
      {repoData.map((repo, index) => {
      return (index === repoData.length - 1) ? (<h1 key={repo.name + index}
 className="repo" ref={callBack}>{repo.name}</h1>) : (<h1 className="repo" key={repo.name + index}>{repo.name}</h1>)
    })}
    </div>
  );
}


이제 관찰자를 정의하고 이를 useRef 후크에 할당해야 합니다. 그리고 useCallback 에서 새로운 교차 관찰자를 생성하고 관찰자 즉 observer.current = new IntersectionObserver(callback, options) 에 할당합니다. 콜백은 IntersectionObserverEntry 객체 목록과 관찰자를 받습니다. IntersectionObserverEntry에는 IntersectionObserverEntry 목록이 있습니다.
대상 요소가 뷰포트와 교차하는지 여부를 확인하기 위해 항목argus[0].isIntersecting을 사용합니다.
이제 이 옵저버observer.current를 사용하여 대상 요소(콜백을 호출하기 위해 옵저버를 적용해야 하는 요소)를 관찰합니다. 우리는 이 옵저버를 마지막 h1 요소, 즉 observer.current.observe(node)에 적용합니다.

if (node) observer.current.observe(node);


콜백이 호출될 때마다 마지막 대상 요소에서 관찰자의 연결을 끊고 새 대상 요소를 다시 관찰해야 합니다. 즉.

if (observer.current) observer.current.disconnect();
if (node) observer.current.observe(node);


이제 마지막useCallback 요소가 뷰포트와 상호 작용할 때마다 h1 함수가 호출되고 가져온 저장소 목록이 repoData 상태로 설정됩니다.

if (argus[0].isIntersecting) {
        if (currentPage < totalRepos / 30) {
          fetchData();
        }
      }




예이!!! 우리는 해냈습니다.
이렇게 하면 무한 스크롤에 대한 반응으로 "Intersection Observer API"를 사용할 수 있습니다.

좋은 웹페이지 즐겨찾기