Description
React version: 19.1.0
eslint-plugin-react-hooks version: 5.2.0
Steps To Reproduce
-
git clone https://github.com/aweebit/eslint-plugin-react-hooks-unstable-reference-issue.git` cd eslint-plugin-react-hooks-unstable-reference-issue npm install
- Run
npm run lint
and observe how there are no warnings. - Run
npm start
, open the served page in your browser and look at the console output.
Link to example repository: https://github.com/aweebit/eslint-plugin-react-hooks-unstable-reference-issue
Here is the full example code:
import { createElement, useEffect, useReducer } from "react";
import { createRoot } from "react-dom/client";
let bar = () => console.log("good");
function Example() {
console.log("rendering");
const [updateTrigger, triggerUpdate] = useReducer(() => ({}), {});
useEffect(() => {
const timeout = setTimeout(triggerUpdate);
return () => clearTimeout(timeout);
}, []);
useEffect(bar, [updateTrigger]);
return null;
}
createRoot(
/** @type {HTMLDivElement} */ (document.getElementById("root"))
).render(createElement(Example));
setTimeout(() =>
setTimeout(() => {
console.log("changing bar");
bar = () => console.log("evil");
})
);
The current behavior
No ESLint warnings
The expected behavior
15:3 warning React Hook useEffect received a function whose dependencies are unknown. Pass an inline function instead react-hooks/exhaustive-deps
Details
The expected behavior is what happens if you write
const foo = { bar: () => console.log("good") };
and replace bar
with foo.bar
everywhere.
The warning makes perfect sense since there is no way for the linter plugin to know for sure foo.bar
doesn't change between renders. But there is also no way for it to know it if a variable declared with let
such as bar
is passed! That's why a warning also has to be produced in that case.
On the other hand, if the variable passed was declared with const
, it is fine to not produce any warning because in that case, the plugin would have a guarantee it's a stable reference.
The issue was discovered in #31207 (comment).