[compiler] Type react-native PanResponder.create to fix react-hooks/r…
GitHub Commits - Example: React

[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 jest in packages/eslint-plugin-react-hooks → 4 suites passed, 5087 tests passed.
  • yarn workspace babel-plugin-react-compiler tsc --noEmit and lint (in compiler/) pass; yarn lint at the root passes; prettier check passes on the changed TS files.
  • cargo check -p react_compiler_hir and cargo fmt --check pass for the Rust change (I did not run the Rust test suite).
  • yarn snap in compiler/: 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 (useMemo config passed to PanResponder.create); with #37975 the eslint-plugin suite passes (5088 tests).
  • yarn flow not 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 jest in packages/eslint-plugin-react-hooks → 4 suites passed, 5087 tests passed.
  • yarn workspace babel-plugin-react-compiler tsc --noEmit and lint (in compiler/) pass; yarn lint at the root passes; prettier check passes on the changed TS files.
  • cargo check -p react_compiler_hir and cargo fmt --check pass for the Rust change (I did not run the Rust test suite).
  • yarn snap in compiler/: 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 (useMemo config passed to PanResponder.create); with #37975 the eslint-plugin suite passes (5088 tests).
  • yarn flow not 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.