-
Notifications
You must be signed in to change notification settings - Fork 49.2k
[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
Conversation
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, []); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
@@ -10,7 +10,7 @@ function Foo() { | |||
|
|||
const onClick = useCallback(() => { | |||
ref.current?.click(); | |||
}, []); | |||
}, [ref]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity what was this for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as below, the ref could change over time
const customRef = useCustomRef(); | ||
let t0; | ||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) { | ||
if ($[0] !== customRef) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that this is functionally equivalent since the box identity never changes, but shouldn't refs be ignored as dependencies for memo blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't know that useCustomRef()
returns a stable ref. it could create two refs and state, and toggle between which ref it returns on each render
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 } ``` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34000). * #34027 * #34026 * #34025 * #34024 * #34005 * #34006 * #34004 * #34003 * __->__ #34000 DiffTrain build for [85bbe39](85bbe39)
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 } ``` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34000). * #34027 * #34026 * #34025 * #34024 * #34005 * #34006 * #34004 * #34003 * __->__ #34000 DiffTrain build for [85bbe39](85bbe39)
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:ref
or-Ref
) and b) the property iscurrent
, 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.useRef()
. We've seen issues with assuming refs are stable.With this change, cases like the following now correctly error:
Stack created with Sapling. Best reviewed with ReviewStack.