-
Notifications
You must be signed in to change notification settings - Fork 46.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Compiler Bug]: Compiler doesn't bail out when reading or writing ref.current
during a render
#29161
Comments
Oh, I didn't notice |
Thanks for posting. First note that refs are fine to access outside of render — in particular, in event handlers and effects. It's okay to access refs in a callback function, so long as that callback is only called outside of render. So in your example, Calling a callback created by this hook during render would mean that (just like accessing a ref) your UI could grow stale. I'd give it a try and see. |
Improves ValidateNoRefAccessInRender, detecting modifications of refs during render. Fixes #29161 [ghstack-poisoned]
…ites of refs" Improves ValidateNoRefAccessInRender, detecting modifications of refs during render. Fixes #29161 [ghstack-poisoned]
Improves ValidateNoRefAccessInRender, detecting modifications of refs during render. Fixes #29161 [ghstack-poisoned]
🥳🥳🥳 |
@josephsavona Thanks for handling this! Our company is trying to figure out how to plan ahead for React 19, and whether we should prioritize removing When you say that |
The other big question I have... there are hundreds of components which use According to |
Since I originally replied, we've improved this validation. It's now on by default and correctly flags the repro above as invalid.
As I noted above, the danger with this implementation is that your UI can grow stale. For example, the compiler may memoize a value based on the fact that the returned ref object never changes, even though it's internal value ( |
Good question. Note that inlining is an optimization strategy - generally compilers (React Compiler included) implement static analysis without relying on inlining. Fundamentally, it's okay to violate the rules of React locally so long as the outer API does follow the rules. The examples here - useStableRef in particular - violate the rules in a way that is visible from the outside. Again, though, if you use them carefully then it can still be okay, but the onus is on you to be careful. |
What kind of issue is this?
Link to repro
https://playground.react.dev/#N4Igzg9grgTgxgUxALhAegFQYDoDsAEG+AYlLnAC4CWEBAJhHAEYA2jA1snoft0diACaVBCzph8AQ3wwEAMwSzc1SSxYBPfGAqTWCfACV5+CEwBWCSvgoALSRXxUJqgO6T1YPvji0wTigjK+C5UttY2+gC2ENoyloEOAG6qUPoA5lSJgQB0Al5eAAowproaWjbQYrgA5A4+kQAOVCz6TJaSUGD6ofiRUDoBznFy+HSwVLhp4QheSnSK+MgAFPkERADKFVBi094Qjc0LcPZwNuFOAPx8aHhyZJQ0BJ0I6zp6RnJLySypAJT4wG4e1wsVkIwAvPhnh8vikEL8ANxAsHZOCwJQOSHfVJIghxCiwAhg3EAXzweEwODWJHu1Foo0YrA4XGp+RARgJMBBUmGigSVFUZQQAEcoKpvIKmJI4OwTAQEFkYJo5opcms2QBVXAsKjsfQAA2eAGFJdL2PqADS7Y5qKUyhkICS4CB1OyTfQuCK4LzzBqBebkEQSU6Sd25ECrHgAFRsTkcEmedEcBEioc0DRY0sdUjgxTAEmgMD28ylXWy+AAkhIemBJAovBQIFCutb9k0WkX6YXiwhS615BBZMEENUst4WqGEHQGxEW1AGlc1jdcHdyHSnl0TbazTCbSw7ex-oC8T4QQ4wfhIc9XqUELvTTLEeS8bJORuEFv92aVnj8PgltkgGSDAaRgP84IAHzDKi6IJABQEgWBFpAn+ADaKF-sMyG-vgAC62F-k+uAkiAJJAA
Repro steps
Our codebase has a core hook called
useStableRef()
which breaks one of the rules of React by mutating a ref during render. This code doesn't trigger thereact-hooks
lint rules, nor does the new React compiler complain when encountering this code.I'm putting this forth in the hopes that the React compiler will bail out when it encounters one of these hooks, instead of compiling these hooks and potentially breaking our codebase when we upgrade.
useStableRef
writes toref.current
in the hook's body. This is a side effect that occurs during rendering!useCallbackRef
calls intouseStableRef
to return a non-reactive callback. In practice, we're using this as a poor-company'suseEffectEvent()
, until that hook is stabilized. Should this function still compile if it calls a hook that doesn't compile?How often does this bug happen?
Every time
What version of React are you using?
React Playground 2024-05-17
The text was updated successfully, but these errors were encountered: