Felipe Evangelista
Felipe Evangelista

Reputation: 139

useCallBack and useEffect infinite loop

According to the code below, I need to call a function whenever inView is true, but using useEffect and useCallback listing the dependencies, I cause an infinite loop. The only ways I managed to avoid it were without listing the dependencies, but I get a warning that I have to list them. I tried only with useEffect, but the result is the same, listing the dependencies, I have a problem with the loops. Here is the code:

import { useEffect, useCallback } from "react";
import { useInView } from "react-intersection-observer";

export const useLazyLoader = (onEnterView: () => void) => {
  const [ref, inView] = useInView({
    triggerOnce: true,
    rootMargin: "-200px",
  });

  const innerEnterView = useCallback(() => {
    onEnterView();
  }, [onEnterView]);

  useEffect(() => {
    inView && innerEnterView();
  }, [inView, innerEnterView]);
  return ref;
};

In this example, if I remove any of the dependencies to try to avoid the problem, I end up getting the warning like this:

Line 16:6:  React Hook useEffect has a missing dependency: 'innerEnterView'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

Upvotes: 4

Views: 3072

Answers (1)

Ionut Bîrsu
Ionut Bîrsu

Reputation: 229

The most probable reason for your infinite loop is onEnterView. To make sure that is the cause, please show us where that function is created. What I think it happens (and I am 99.99% sure about it) is you create an arrow function in some parent (without wrapping it in useCallback). Calling onEnterView makes that parent re-render (you said you called dispatch) , which also mean the onEnterView function's reference will change. The result is you get a new onEnterView every time you call useLazyLoader hook, so the useCallback you have in place there is pretty much useless (you get a different dependency every time, so he recreates the useCallback result). To fix your problem, please wrap the onEnterView in useCallback where is defined, rather than where it is used.

Upvotes: 5

Related Questions