Skip to content

Commit

Permalink
Fix type definition of useMergeRefs (facebook#41700)
Browse files Browse the repository at this point in the history
Summary:

The type definition of `useMergeRefs` is incorrect, which forces all callsites to use `$FlowFixMe`. This fixes the definition and removes all the `$FlowFixMe`s caused by it.

Changelog: [internal]

Reviewed By: javache

Differential Revision: D51660716
  • Loading branch information
rubennorte authored and facebook-github-bot committed Nov 29, 2023
1 parent dc405f2 commit 8f396fc
Show file tree
Hide file tree
Showing 7 changed files with 10 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const AnimatedScrollViewWithInvertedRefreshControl = React.forwardRef(
Props,
Instance,
>(intermediatePropsForScrollView);
const ref = useMergeRefs<Instance | null>(scrollViewRef, forwardedRef);
const ref = useMergeRefs<Instance>(scrollViewRef, forwardedRef);

return (
// $FlowFixMe[incompatible-use] Investigate useAnimatedProps return value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ export default function createAnimatedComponent<TProps: {...}, TInstance>(
// $FlowFixMe[incompatible-call]
props,
);
// $FlowFixMe[incompatible-call]
const ref = useMergeRefs<TInstance | null>(callbackRef, forwardedRef);
const ref = useMergeRefs<TInstance>(callbackRef, forwardedRef);

// Some components require explicit passthrough values for animation
// to work properly. For example, if an animated component is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ const ScrollViewStickyHeaderWithForwardedRef: React.AbstractComponent<
}, []);
const ref: (React.ElementRef<typeof Animated.View> | null) => void =
// $FlowFixMe[incompatible-type] - Ref is mutated by `callbackRef`.
// $FlowFixMe[incompatible-call]
useMergeRefs<Instance | null>(callbackRef, forwardedRef);
useMergeRefs<Instance>(callbackRef, forwardedRef);

const offset = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ const SwitchWithForwardedRef: React.AbstractComponent<
typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent,
> | null>(null);

// $FlowFixMe[incompatible-call]
const ref = useMergeRefs(nativeSwitchRef, forwardedRef);

const [native, setNative] = React.useState({value: (null: ?boolean)});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1287,10 +1287,7 @@ function InternalTextInput(props: Props): React.Node {
[mostRecentEventCount, viewCommands],
);

const ref = useMergeRefs<TextInputInstance | null>(
setLocalRef,
props.forwardedRef,
);
const ref = useMergeRefs<TextInputInstance>(setLocalRef, props.forwardedRef);

const _onChange = (event: ChangeEvent) => {
const currentText = event.nativeEvent.text;
Expand Down
4 changes: 1 addition & 3 deletions packages/react-native/Libraries/Image/ImageInjection.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,8 @@ export function useWrapRefWithImageAttachedCallbacks(
}

// `useMergeRefs` returns a stable ref if its arguments don't change.
return useMergeRefs<ImageInstance | null>(
// $FlowFixMe[incompatible-call]
return useMergeRefs<ImageInstance>(
forwardedRef,
// $FlowFixMe[incompatible-call]
imageAttachedCallbacksRef.current,
);
}
14 changes: 5 additions & 9 deletions packages/react-native/Libraries/Utilities/useMergeRefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@
* @format
*/

import * as React from 'react';
import {useCallback} from 'react';

type CallbackRef<T> = T => mixed;
type ObjectRef<T> = {current: T, ...};

type Ref<T> = CallbackRef<T> | ObjectRef<T>;

/**
* Constructs a new ref that forwards new values to each of the given refs. The
* given refs will always be invoked in the order that they are supplied.
Expand All @@ -24,11 +20,11 @@ type Ref<T> = CallbackRef<T> | ObjectRef<T>;
* the returned callback ref is supplied as a `ref` to a React element, this may
* lead to problems with the given refs being invoked more times than desired.
*/
export default function useMergeRefs<T>(
...refs: $ReadOnlyArray<?Ref<T>>
): CallbackRef<T> {
export default function useMergeRefs<Instance>(
...refs: $ReadOnlyArray<?React.RefSetter<Instance>>
): (Instance | null) => void {
return useCallback(
(current: T) => {
(current: Instance | null) => {
for (const ref of refs) {
if (ref != null) {
if (typeof ref === 'function') {
Expand Down

0 comments on commit 8f396fc

Please sign in to comment.