[react-compiler] Skip hook validation for method calls on untyped module imports#35858
Open
sleitor wants to merge 2 commits intofacebook:mainfrom
Open
[react-compiler] Skip hook validation for method calls on untyped module imports#35858sleitor wants to merge 2 commits intofacebook:mainfrom
sleitor wants to merge 2 commits intofacebook:mainfrom
Conversation
…ule imports
Third-party libraries like amCharts export objects with methods named
`useTheme()`, `useData()`, etc. that are not React hooks. The React
Compiler's ESLint plugin incorrectly flags these as hook violations
because the hook detection heuristic treats any `use*`-named property
as a potential hook.
This change tracks identifiers loaded from module imports (ImportDefault,
ImportNamespace, ImportSpecifier) whose types are unresolved by the type
system. For MethodCall instructions where the receiver is one of these
untyped imports, we skip hook validation since the `use*` property was
typed heuristically based on naming alone, not from actual type info.
This preserves correct behavior for:
- `import React from 'react'; React.useState()` (typed receiver)
- `const React = require('react'); React.useState()` (ModuleLocal, not import)
- Direct hook calls like `useHook()` (CallExpression, not MethodCall)
Fixes facebook#32109
Member
|
ooops, meant to reply to a different PR that you sent today. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
Third-party libraries like amCharts export objects with methods named
useTheme(),useData(), etc. that are not React hooks. The React Compiler's ESLint plugin incorrectly flags these as hook violations because the hook detection heuristic treats anyuse*-named property as a potential hook.This change tracks identifiers loaded from module imports (
ImportDefault,ImportNamespace,ImportSpecifier) whose types are unresolved by the type system. ForMethodCallinstructions where the receiver is one of these untyped imports, we skip hook validation since theuse*property was typed heuristically based on naming alone, not from actual type info.How it works
In
ValidateHooksUsage.ts:Track untyped import identifiers: During
LoadGlobalprocessing, we record identifiers that come from import bindings but have unresolved types (notObjectorFunctionwith known shapes).Skip hook validation for MethodCalls on untyped imports: When processing a
MethodCall, if the receiver is an untyped import, we skip the hook conditional/dynamic usage checks.Handle nested function expressions: In
visitFunctionExpression, we similarly skip hook-in-callback validation for method calls on untyped receivers.What's preserved
import React from 'react'; React.useState()— React has a known type, so hook validation is preserved ✅const React = require('react'); React.useState()—Reactis aModuleLocalbinding (not an import), so it's not tracked as an untyped import and hook validation is preserved ✅useHook()— These areCallExpressions, notMethodCalls, so they're unaffected ✅import {useHook} from 'some-lib'; useHook()— Direct import of a hook-named function still validates correctly ✅Test plan
amCharts.useTheme()in conditional blocks no longer errorsReact.useState()in conditional blocks still errors (both import and require styles)useHook()calls in conditional blocks still errorFixes #32109