Feature proposal(eslint-react-hooks): don't require empty dependency useCallback in another dependency array
See original GitHub issueConsider the following:
const [mouseDown, setMouseDown] = useState(false);
const onMouseDown = useCallback(() => {
setMouseDown(true);
}, []);
const onMouseMove = useCallback(e => { /* ... */ }, []);
const onMouseUp = useCallback(() => {
setMouseDown(false);
}, []);
useEffect(() => {
if (mouseDown) {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
return () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
}
}, [mouseDown]);
Above the useEffect()
will complain that it didn’t receive onMouseMove
and onMouseUp
in its dependency array and it’s correct. But it could be smarter, because they were all defined by useCallback(() => {}, [])
meaning they will all remain the same value throughout the lifetime of this component.
Given this information I could write
useEffect(() => {
if (mouseDown) {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
return () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
}
}, [mouseDown, onMouseMove, onMouseUp]);
To satisfy the linter and that would work but only because I know they were defined by useCallback(() => {}, [])
. If someone were to change the dependency array for onMouseMove
or onMouseUp
this would now break (the event listeners won’t be removed and readded if onMouseMove
changes for instance), but the linter will be happy.
However if I was able to specify it like I did in the first example it is the same as saying, this works as long as these specific variables don’t change, if someone unwittingly changes the dependency array of onMouseMove
the linter would shout at them again and they would have to rewrite this into something more flexible.
This is similar to the way useCallback
doesn’t complain about my usage of setMouseDown
as it knows it can’t change.
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (4 by maintainers)
No prob.
To give you a little more insight, there are only ~6 core contributors to this repo right now and we’re spread pretty thin. If you feel strongly about this issue, you’d probably have a lot better luck championing it through by submitting a PR (with tests!) 😄
Admittedly I skimmed this pretty quickly, saw that you were proposing a change to the dependencies array, and closed it with a canned response. If I had scanned more carefully I probably would have left it open for discussion. My apologies. (I don’t think it’s quite the same as #19125 or I would suggest leaving it closed as a duplicate.)
The updater function returned by
useState
, or thedispatch
function returned byuseReducer
, are known by React to be stable. Other values are not, although I see why in this case, you could reason that the functions are stable.