react: [react-hooks/exhaustive-deps] Does not complain for nested dependencies if the parent object is added in dependencies array
React version: 17.0.0-rc.0
Steps To Reproduce
- add a
useEffectwhich does something withhistory.location.hashandhistory.push - The eslint hook complains that you should have a dependency on
history. I understand that is because we are passinghistoryasthisto thepushfunction - If you add
historyto dependencies, it will stop complaining, althoughhistory.location.hashcan change withouthistoryobject itself being changed.
Link to code example: https://codesandbox.io/s/react-router-usehistory-hooks-forked-2p5mk?file=/src/App.js
The current behavior
- lint rule does not complain or suggest anything related to destructuring the nested properties, or adding them explicitly after the top level object is added
The expected behavior
- if possible, it can show similar suggestions as it does when the whole props object is specified as a dependency
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (9 by maintainers)
location is immutable , it comes from react router.
https://reactrouter.com/web/api/history#:~:text=The history object is mutable,are correct in lifecycle hooks.
This sounds reasonable. You can usually do something like this with refs.
In general, the guideline is that effects should be resilient to occasionally re-running. If it is super important that the code inside doesn’t reexecute unless some specific case happens, it is best to code it explicitly.
Yes.
This sounds somewhat fragile. If it re-renders because some router prop changed, then you should use that prop/context to determine “where you are” rather than reading it from a mutable object.
The lint rule can’t guess we’re dealing with a mutable object in this case, so it assumes this is a regular piece of data.
If you’re using a mutable object in dependencies, specifying its properties as dependencies is going to lead to confusing behaviors because you can never be sure whether it was updated “just in time” before a React render or slightly afterwards (in which case you’ll “miss” the chance to respond to it).
In general, reading mutable data during render (which is what you’re doing when you read
history.somethingto put it in dependency list) is a fragile pattern.