[compiler] Type react-native PanResponder.create to fix react-hooks/r…
Fixes #37955 Depends on #37975 (retains declared Freeze effects for already-frozen values, as suggested by @javache). Until that merges this PR's diff also shows its commit.
Summary
react-hooks/refs reports "Passing a ref to a function may read its value during render" for callbacks passed to React Native's PanResponder.create({...}), because the compiler treats PanResponder imported from react-native as an unknown function that may call its arguments during render.
PanResponder.create() only stores the handlers and invokes them later from gesture events. The compiler already has a signature for exactly this (PanResponder.create freezes its config and doesn't call it during render), but it only exists in the test-only shared-runtime type provider in snap, so real code never gets it.
This adds the same signature for react-native to defaultModuleTypeProvider (TypeScript, and the Rust port in default_module_type_provider.rs), so the callbacks are treated as deferred, like the IntersectionObserver fix in #37764. Other unknown functions still report errors when given ref-accessing callbacks.
How did you test this change?
Added a valid case to packages/eslint-plugin-react-hooks/__tests__/ReactCompilerRuleTypescript-test.ts (the repro shape from the issue). Snap fixtures can't cover this because snap replaces the module type provider with its own.
- Without the fix:
cd packages/eslint-plugin-react-hooks && npx jest ReactCompilerRuleTypescript→1 failed, 15 passed(the new case). - With the fix:
yarn build:compiler && npx jestinpackages/eslint-plugin-react-hooks→4 suites passed, 5087 tests passed. yarn workspace babel-plugin-react-compiler tsc --noEmitandlint(incompiler/) pass;yarn lintat the root passes; prettier check passes on the changed TS files.cargo check -p react_compiler_hirandcargo fmt --checkpass for the Rust change (I did not run the Rust test suite).yarn snapincompiler/: identical results with and without this change (1812 passed, 20 failed; the failures are pre-existing, mostly fbt fixtures in my local setup).- Also added a memoized-config case (
useMemoconfig passed toPanResponder.create); with #37975 the eslint-plugin suite passes (5088 tests). yarn flownot run: the change touches no Flow-typed code.
🤖 Generated with Claude Code
Co-authored-by: Claude Sonnet 5.5 n******@anthropic.com
Repository navigation
Commit 9ca7a27 [compiler] Type react-native PanResponder.create to fix react-hooks/refs false positive (#37970)
Fixes #37955 Depends on #37975 (retains declared Freeze effects for already-frozen values, as suggested by @javache). Until that merges this PR's diff also shows its commit.
Summary
react-hooks/refs reports "Passing a ref to a function may read its value during render" for callbacks passed to React Native's PanResponder.create({...}), because the compiler treats PanResponder imported from react-native as an unknown function that may call its arguments during render.
PanResponder.create() only stores the handlers and invokes them later from gesture events. The compiler already has a signature for exactly this (PanResponder.create freezes its config and doesn't call it during render), but it only exists in the test-only shared-runtime type provider in snap, so real code never gets it.
This adds the same signature for react-native to defaultModuleTypeProvider (TypeScript, and the Rust port in default_module_type_provider.rs), so the callbacks are treated as deferred, like the IntersectionObserver fix in #37764. Other unknown functions still report errors when given ref-accessing callbacks.
How did you test this change?
Added a valid case to packages/eslint-plugin-react-hooks/__tests__/ReactCompilerRuleTypescript-test.ts (the repro shape from the issue). Snap fixtures can't cover this because snap replaces the module type provider with its own.
- Without the fix:
cd packages/eslint-plugin-react-hooks && npx jest ReactCompilerRuleTypescript→1 failed, 15 passed(the new case). - With the fix:
yarn build:compiler && npx jestinpackages/eslint-plugin-react-hooks→4 suites passed, 5087 tests passed. yarn workspace babel-plugin-react-compiler tsc --noEmitandlint(incompiler/) pass;yarn lintat the root passes; prettier check passes on the changed TS files.cargo check -p react_compiler_hirandcargo fmt --checkpass for the Rust change (I did not run the Rust test suite).yarn snapincompiler/: identical results with and without this change (1812 passed, 20 failed; the failures are pre-existing, mostly fbt fixtures in my local setup).- Also added a memoized-config case (
useMemoconfig passed toPanResponder.create); with #37975 the eslint-plugin suite passes (5088 tests). yarn flownot run: the change touches no Flow-typed code.
🤖 Generated with Claude Code
Co-authored-by: Claude Sonnet 5.5
1 parent a6b912f commit 9ca7a27 3 files changed Lines changed: 152 additions & 3 deletions File tree - compiler - crates/react_compiler_hir/src - packages/babel-plugin-react-compiler/src/HIR - packages/eslint-plugin-react-hooks/tests
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| 11 | 11 | |
| 12 | 12 | |
| 13 | 13 | |
| 14 | - | |
| 15 | - | |
| 14 | + | |
| 15 | + | |
| 16 | 16 | |
| 17 | 17 | |
| 18 | 18 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| 115 | 115 | |
| 116 | 116 | |
| 117 | 117 | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 118 | 170 | |
| 119 | 171 | |
| 120 | 172 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| 5 | 5 | |
| 6 | 6 | |
| 7 | 7 | |
| 8 | - | |
| 8 | + | |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| 115 | 115 | |
| 116 | 116 | |
| 117 | 117 | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 118 | 168 | |
| 119 | 169 | |
| 120 | 170 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| 234 | 234 | |
| 235 | 235 | |
| 236 | 236 | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 237 | 284 | |
| 238 | 285 | |
| 239 | 286 |
0 commit comments
Comments
No comments yet. Start the discussion.