Small refactor of image attached callbacks logic (#41701)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41701

I did a hotfix for this logic in D51618512. This does a small refactor to improve the code (moving more shared code to the hook and avoiding creating a closure unnecessarily in every call to it).

Changelog: [internal]

Reviewed By: javache

Differential Revision: D51660288

fbshipit-source-id: 472836840b19958402bd0de3e2c09c7cec004156
This commit is contained in:
Rubén Norte
2023-11-29 12:00:29 -08:00
committed by Facebook GitHub Bot
parent 10b3e0e868
commit c120ccb7ee
3 changed files with 35 additions and 38 deletions
@@ -15,11 +15,10 @@ import type {AbstractImageAndroid, ImageAndroid} from './ImageTypes.flow';
import flattenStyle from '../StyleSheet/flattenStyle';
import StyleSheet from '../StyleSheet/StyleSheet';
import TextAncestor from '../Text/TextAncestor';
import useMergeRefs from '../Utilities/useMergeRefs';
import ImageAnalyticsTagContext from './ImageAnalyticsTagContext';
import {
unstable_getImageComponentDecorator,
useRefWithImageAttachedCallbacks,
useWrapRefWithImageAttachedCallbacks,
} from './ImageInjection';
import {getImageSourcesFromImageProps} from './ImageSourceUtils';
import {convertObjectFitToResizeMode} from './ImageUtils';
@@ -200,15 +199,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
const resizeMode =
objectFit || props.resizeMode || style?.resizeMode || 'cover';
const imageAttachedCallbacksRef = useRefWithImageAttachedCallbacks();
const actualRef =
useMergeRefs<React.ElementRef<AbstractImageAndroid> | null>(
// $FlowFixMe[incompatible-call]
forwardedRef,
// $FlowFixMe[incompatible-call]
imageAttachedCallbacksRef,
);
const actualRef = useWrapRefWithImageAttachedCallbacks(forwardedRef);
return (
<ImageAnalyticsTagContext.Consumer>
@@ -15,11 +15,10 @@ import type {AbstractImageIOS, ImageIOS} from './ImageTypes.flow';
import {createRootTag} from '../ReactNative/RootTag';
import flattenStyle from '../StyleSheet/flattenStyle';
import StyleSheet from '../StyleSheet/StyleSheet';
import useMergeRefs from '../Utilities/useMergeRefs';
import ImageAnalyticsTagContext from './ImageAnalyticsTagContext';
import {
unstable_getImageComponentDecorator,
useRefWithImageAttachedCallbacks,
useWrapRefWithImageAttachedCallbacks,
} from './ImageInjection';
import {getImageSourcesFromImageProps} from './ImageSourceUtils';
import {convertObjectFitToResizeMode} from './ImageUtils';
@@ -162,14 +161,7 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => {
};
const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel;
const imageAttachedCallbacksRef = useRefWithImageAttachedCallbacks();
const actualRef = useMergeRefs<React.ElementRef<AbstractImageIOS> | null>(
// $FlowFixMe[incompatible-call]
forwardedRef,
// $FlowFixMe[incompatible-call]
imageAttachedCallbacksRef,
);
const actualRef = useWrapRefWithImageAttachedCallbacks(forwardedRef);
return (
<ImageAnalyticsTagContext.Consumer>
+31 -17
View File
@@ -14,6 +14,7 @@ import type {
Image as ImageComponent,
} from './ImageTypes.flow';
import useMergeRefs from '../Utilities/useMergeRefs';
import * as React from 'react';
import {useRef} from 'react';
@@ -52,24 +53,37 @@ export function unstable_unregisterImageAttachedCallback(
imageAttachedCallbacks.delete(callback);
}
export function useRefWithImageAttachedCallbacks(): React.RefSetter<ImageInstance> {
export function useWrapRefWithImageAttachedCallbacks(
forwardedRef: React.RefSetter<ImageInstance>,
): React.RefSetter<ImageInstance> {
const pendingCleanupCallbacks = useRef<Array<() => void>>([]);
const ref = useRef((node: ImageInstance | null) => {
if (node == null) {
if (pendingCleanupCallbacks.current.length > 0) {
pendingCleanupCallbacks.current.forEach(cb => cb());
pendingCleanupCallbacks.current = [];
}
} else {
imageAttachedCallbacks.forEach(imageAttachedCallback => {
const maybeCleanupCallback = imageAttachedCallback(node);
if (maybeCleanupCallback != null) {
pendingCleanupCallbacks.current.push(maybeCleanupCallback);
}
});
}
});
const imageAttachedCallbacksRef =
useRef<?(node: ImageInstance | null) => void>(null);
return ref.current;
if (imageAttachedCallbacksRef.current == null) {
imageAttachedCallbacksRef.current = (node: ImageInstance | null): void => {
if (node == null) {
if (pendingCleanupCallbacks.current.length > 0) {
pendingCleanupCallbacks.current.forEach(cb => cb());
pendingCleanupCallbacks.current = [];
}
} else {
imageAttachedCallbacks.forEach(imageAttachedCallback => {
const maybeCleanupCallback = imageAttachedCallback(node);
if (maybeCleanupCallback != null) {
pendingCleanupCallbacks.current.push(maybeCleanupCallback);
}
});
}
};
}
// `useMergeRefs` returns a stable ref if its arguments don't change.
return useMergeRefs<ImageInstance | null>(
// $FlowFixMe[incompatible-call]
forwardedRef,
// $FlowFixMe[incompatible-call]
imageAttachedCallbacksRef.current,
);
}