Skip to content

[compiler] Fixes to enableTreatRefLikeIdentifiersAsRefs #34000

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

josephsavona
Copy link
Member

@josephsavona josephsavona commented Jul 25, 2025

We added the @enableTreatRefLikeIdentifiersAsRefs feature a while back but never enabled it. Since then we've continued to see examples that motivate this mode, so here we're fixing it up to prepare to enable by default. It now works as follows:

  • If we find a property load or property store where both a) the object's name is ref-like (ref or -Ref) and b) the property is current, we infer the object itself as a ref and the value of the property as a ref value. Originally the feature only detected property loads, not stores.
  • Inferred refs are not considered stable (this is a change from the original implementation). The only way to get a stable ref is by calling useRef(). We've seen issues with assuming refs are stable.

With this change, cases like the following now correctly error:

function Foo(props) {
  const fooRef = props.fooRef;
  fooRef.current = true;
  ^^^^^^^^^^^^^^ cannot modify ref in render
}

Stack created with Sapling. Best reviewed with ReviewStack.

@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Jul 25, 2025
We added the `@enableTreatRefLikeIdentifiersAsRefs` feature a while back but never enabled it. Since then we've continued to see examples that motivate this mode, so here we're fixing it up to prepare to enable by default. It now works as follows:

* If we find a property load or property store where both a) the object's name is ref-like (`ref` or `-Ref`) and b) the property is `current`, we infer the object itself as a ref and the value of the property as a ref value. Originally the feature only detected property loads, not stores.
* Inferred refs are not considered stable (this is a change from the original implementation). The only way to get a stable ref is by calling `useRef()`. We've seen issues with assuming refs are stable.

With this change, cases like the following now correctly error:

```js
function Foo(props) {
  const fooRef = props.fooRef;
  fooRef.current = true;
  ^^^^^^^^^^^^^^ cannot modify ref in render
}
```
@@ -1211,6 +1211,8 @@ addObject(BUILTIN_SHAPES, BuiltInRefValueId, [
['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
]);

addObject(BUILTIN_SHAPES, ReanimatedSharedValueId, []);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this i got errors trying to resolve properties, because we have a shape id defined for reanimated but no shape definition. I'm not sure how we didn't run into that error before but it seems like it easily could have occurred.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the error was an invariant which i don't think we report in eslint, so the compiler may have just been silently failing for folks using reanimated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants