-
Notifications
You must be signed in to change notification settings - Fork 47.5k
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]: Mutating a ref returned from a function warns #29196
Comments
Thanks for posting! The cause is very similar to #29160 (comment) — the compiler currently assumes that only values that come directly from |
I'm looking into adding this. Assigning this to myself |
If a component uses the `useRef` hook directly then we type it's return value as a ref. But if it's wrapped in a custom hook then we lose out on this type information as the compiler doesn't look at the hook definition. This has resulted in some false positives in our analysis like the ones reported in facebook#29160 and facebook#29196. This PR will treat objects named as `ref` or if their names end with the substring `Ref`, and contain a property named `current`, as React refs. ``` const ref = useMyRef(); const myRef = useMyRef2(); useEffect(() => { ref.current = ...; myRef.current = ...; }) ``` In the above example, `ref` and `myRef` will be treated as React refs.
If a component uses the `useRef` hook directly then we type it's return value as a ref. But if it's wrapped in a custom hook then we lose out on this type information as the compiler doesn't look at the hook definition. This has resulted in some false positives in our analysis like the ones reported in facebook#29160 and facebook#29196. This PR will treat objects named as `ref` or if their names end with the substring `Ref`, and contain a property named `current`, as React refs. ``` const ref = useMyRef(); const myRef = useMyRef2(); useEffect(() => { ref.current = ...; myRef.current = ...; }) ``` In the above example, `ref` and `myRef` will be treated as React refs.
If a component uses the `useRef` hook directly then we type it's return value as a ref. But if it's wrapped in a custom hook then we lose out on this type information as the compiler doesn't look at the hook definition. This has resulted in some false positives in our analysis like the ones reported in #29160 and #29196. This PR will treat objects named as `ref` or if their names end with the substring `Ref`, and contain a property named `current`, as React refs. ``` const ref = useMyRef(); const myRef = useMyRef2(); useEffect(() => { ref.current = ...; myRef.current = ...; }) ``` In the above example, `ref` and `myRef` will be treated as React refs.
The error you're encountering happens because mutating a prop or a hook argument directly inside a hook is not allowed in React. The error arises because the target ref passed to the useResizeHandle hook is being directly mutated, which React warns against. To resolve this, you should avoid directly modifying the target ref and instead use a local variable to track changes or update the target element in a way that doesn't involve directly mutating the passed reference. Modified one: export function useResizeHandle( React.useEffect(() => {
}, [target]); // target ref is a dependency here, but we don't mutate it directly return { Key Changes on the above code: Check for Existence and Added a check to ensure that bar.current and target.current are not null before accessing their properties. Note: |
Here's another variant of this issue - passing ref as a prop to a child component causes Compiler to not recognize it as a ref. If you set |
What kind of issue is this?
Link to repro
https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEUYCAsgJ4BKCaAFAJRHAA6xRMCOsxpCtBowDc7AL7t2GbPkJEAEggA2SiExbsiROITA5OdIgF4SZKoKaiO-AKJo0CXPXVGAfBo5auaAHRxYXJj6JgDkOAh6IVZaYiLiIGJAA
Repro steps
When consuming mutable refs from custom hooks (or via props), the consuming components should be allowed to mutate them inside effects/event handlers.
How often does this bug happen?
Every time
What version of React are you using?
19
The text was updated successfully, but these errors were encountered: