React, Next, Redux/🚀 React with Hooks

useCallback과 useRef를 이용한 infinite Scrolling

DarrenKwonDev 2020. 4. 19. 02:16

 

정리 중입니다

 

import React, { useEffect, useState, useCallback, useRef } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import { getMovies } from "./api";

const App = () => {
  const [page, setPage] = useState(1);
  const [movie, setMovie] = useState([]);
  const [loading, setLoading] = useState(false);

  const observer = useRef();

  const lastMovieElementRef = useCallback(
    (e) => {
      if (loading) return;
      if (observer.current) observer.current.disconnect();
      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) {
          console.log("bottom");
          const getNewMovie = async () => {
            setLoading(true);
            setPage(page + 1);
            const newMovie = await getMovies(page);
            const {
              data: {
                data: { movies },
              },
            } = newMovie;
            console.log(movies);
            setMovie(movie.concat(movies));
            setLoading(false);
          };
          getNewMovie();
        }
      });
      if (e) observer.current.observe(e);
    },
    [page, movie, loading]
  );

  useEffect(() => {
    const getMovieLiest = async () => {
      const movieList = await getMovies(page);
      const {
        data: {
          data: { movies },
        },
      } = movieList;
      setMovie(movies);
    };
    getMovieLiest();
  }, [movie]);

  return (
    <>
      <div>
        <div>
          {movie.map((e, i) => {
            if (movie.length === i + 1) {
              return (
                <h3 key={e.id} ref={lastMovieElementRef}>
                  {e.title}
                </h3>
              );
            }
            return <h3 key={e.id}>{e.title}</h3>;
          })}
        </div>
        <div>{loading && "Loading..."}</div>
      </div>
    </>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);