Search code examples
reactjsreact-hookseslintuse-effect

Keep data adding even I do not click load more in React


I try to figure it out by myself and search StackOverflow, but I could not figure it out.

I solved dependency and another warning.

But when I run this code, my data keep adding the next pages automatically.

I think this problem is because of this code:

useEffect(() => {
        fetchingNextMovie();
      }, [fetchingNextMovie]); //if I make empty array, it is working fine. but I have an dependency warning.

my code is:

export default function Mainpage() {
  const [movies, setMovies] = useState([]);
  const [search, setSearch] = useState("");
  const [number, setNumber] = useState(1);
  const API = process.env.REACT_APP_API_KEY;
  const movie = `https://api.themoviedb.org/3/search/movie?api_key=${API}&language=en_US&page=${number}&query=${search}`;
  const popularMovie = `https://api.themoviedb.org/3/movie/popular?api_key=${API}&language=en-US&page=${number}`;

  const fetchdata = useCallback(async () => {
    let curURL = ``;
    if (search === "") {
      curURL = popularMovie;
    } else {
      curURL = movie;
    }
    const res = await axios.get(curURL);
    const data = res.data;
    return data;
  }, [movie, popularMovie, search]);

  const savedHeight = document.body.offsetHeight;

  const fetchingNextMovie = useCallback(() => {
    fetchdata().then((randomData) => {
      const newMovies = [...movies, ...randomData.results];
      setMovies(newMovies);
      window.scrollTo(0, savedHeight);
      // setTotalPage(randomData.total_pages);
      setNumber(randomData.page + 1);
    });
  }, [fetchdata, movies, savedHeight]);

  useEffect(() => {
    fetchingNextMovie();
  }, [fetchingNextMovie]);

  const onClick = () => {
    fetchingNextMovie();
  };

  return (
    <div>
      <Search setSearch={setSearch} />
      <MovieComponent movies={movies} />
      {/* <Paging setNumber={setNumber} totalPage={totalPage} /> */}
      <div className="loadButton" style={{ marginTop: "20px" }}>
        <button onClick={onClick}>Load More</button>
      </div>
    </div>
  );
}

Solution

  • This seems more like an eslint warning regarding react-hooks/exhaustive-deps.

    If you are absolutely sure you want some logic to run only when the component mounts, then specifying an empty dependency array ([]) is the equivalent of a class-based component's componentDidMount lifecycle method.

    React useEffect

    If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

    You can ignore the warning, or disable the linting rule specifically for that line.

    Example:

    useEffect(() => {
      // other component logic to run when component mounts
    
      ...
    
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);