eslint-plugin-react-hooks: JSX support for react-hooks/exhaustive-deps (#18051) #19868
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
As mentioned in the discussion, ESLint does not implement React-specific logic, and therefore JSX Identifiers will not be treated by ESLint as regular variables with references to them in scopes.
Because of this circumstance, when we collect hook callback dependencies, JSX variables don't end up in the list of dependencies and JSX-component variables declared in the hook dependencies array are considered exhaustive, but they are not.
So I implemented a prototype of a possible solution to this problem — handling JSX-expressions in the dependency gathering logic of the plugin.
In a nutshell, if JSX is found in the callback hook, then I traverse the JSX tree of elements and collect a list of React components. In the process, I filter out all elements that are not React components. Then I add the resulting array to the list of collected dependencies, which will be checked for exhaustiveness or lack of dependencies.
My prototype solution is imperfect at the moment, it doesn't find JSX-expressions in if/else constructions, it does not fully support JSXMemberExpressions, I have not yet written Typescript tests, etc. But I will do my best if I know that this is the right way.
Thanks!
Test Plan
✅ All test, test-prod, lint, flow checks are passed.
Added some new tests for positive and negative cases of JSX support.