-
Notifications
You must be signed in to change notification settings - Fork 655
Description
useRefObjectAsForwardedRef calculates the ref target only one time, on initial calculation (since #7553). This can cause the target to be stale if it changes after the initial calculation (which happens during the effect cycle), subtly returning old values that look the same but aren't.
For example, a ref on the following component will continue to refer to an HTMLInputElement even if asInput becomes false later:
function StaleForwardedRef({ref: forwardedRef, asInput}) {
const ref = useRef(null)
useRefObjectAsForwardedRef(ref, fowardedRef)
return asInput ? <input ref={ref} /> : <button ref={ref} />
}The solution is to remove the dependency array introduced in #7553. Since ref targets can change at any time, we can't assume they will remain constant for the lifecycle of the component. And ref targets are not reactive values, so we can't just update the dependency array to be [ref.current].
The dependency array was introduced for performance, but the cost of calculating the ref is essentially 0 since the function is just () => ref.current -- in fact, it might actually be faster than checking the dependency array!