Reputation: 139
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
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