Open sajera opened 1 week ago
I believe the issue is related to how react-hooks/exhaustive-deps interprets dependencies when using external object method. The warning arises because useEffect receives a function (foo.bar) that isn't declared inline, causing EsLint to think that it might change between renders.
Proposed Solution: Use an inline function
One way to resolve this is by using an inline function within useEffect:
useEffect(() => {
console.log('Do something once at component mount');
}, []);
return <div />;
});
This approach eliminates the warning because the function is defined directly inside useEffect and does not have unknown dependencies.
Alternative Solution: Use useCallback to Memoize the Function If you prefer to use the method foo.bar, you can memoize it using
useCallback:
export default memo(function Example() {
const stableBar = useCallback(foo.bar, []);
useEffect(stableBar, []);
return <div />;
});
This will ensure foo.bar is treated as a stable reference, avoiding unnecessary re-renders and warnings.
Let me know if this helps resolve the issue!
/assigned
You might have mismatching versions of React and the renderer (such as React DOM). You might be breaking the Rules of Hooks. You might have more than one copy of React in the same app. Please refer to React's documentation for tips on how to debug and fix this problem.
It seems that in your case, you passed a named function (foo.bar) directly to useEffect, which caused React to have difficulty understanding the dependencies of that function.
The solution to this issue is to use an inline function or an arrow function instead. This will provide React with a clearer understanding of the dependencies, allowing it to manage the effect correctly.
@Tanmayshi - You're right. I know several ways to avoid this warning, but I think the rules are flawed. They shouldn't guess; they should help prevent errors or unexpected behavior. In my case, the code is clear and error-free, so this warning seems like a bug.
P.S. Your code example looks massive. I just don't like using that coding style ;)
P.S. 2 useCallback(foo.bar, []) is logically unexpected here and requires at least some additional explanation. useEffect(foo.bar, []) clearly indicates that we expect only the component's mount and unmount events.
BTW more samples of unexpected behavior based on your comments:
const foo = { bar: () => console.log('Do something once at component mount') }
const e1 = memo(function Example () { useEffect(foo.bar, []) // throw warning return
})const e2 = memo(function Example () { useCallback(foo.bar, []) // not to throw warning ? return
})2. **useEffect**, from a rule perspective, behaves differently depending on the parent object of the function. Why is that?
const foo = () => console.log('Do something once at component mount')
const e1 = memo(function Example () { useEffect(foo, []) // not to throw warning ? return
})
A fairly simple and straightforward code sample is causing a warning. I might be wrong, and I apologize if that's the case, but this seems like a bug on your end.
React Hook useEffect received a function whose dependencies are unknown. Pass an inline function instead
React version: ^18.2.0
Steps To Reproduce
As you might guess, there is a function that should be triggered once when the component mounts. It returns undefined...
The current behavior
Throws the warning: React Hook useEffect received a function whose dependencies are unknown. Pass an inline function instead
The expected behavior
Not to throw