Define debugging name for multiple components (#41516)

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

This cleans up some dead code in animated components (some wrappers that actually don't do anything), which in this case leads to component names being properly defined for debugging in React DevTools, etc.

Changelog: [internal]

Reviewed By: sammy-SC

Differential Revision: D51401568

fbshipit-source-id: 0de43f526b77a6b83e66e03f0ffa8d42c2b77112
This commit is contained in:
Rubén Norte
2023-11-16 12:23:22 -08:00
committed by Facebook GitHub Bot
parent 5730f560b9
commit fa89dd68b0
5 changed files with 82 additions and 106 deletions
@@ -14,22 +14,7 @@ import FlatList from '../../Lists/FlatList';
import createAnimatedComponent from '../createAnimatedComponent';
import * as React from 'react';
/**
* @see https://github.com/facebook/react-native/commit/b8c8562
*/
const FlatListWithEventThrottle = React.forwardRef(
// $FlowFixMe[incompatible-call]
(
props: React.ElementConfig<typeof FlatList>,
ref:
| ((null | FlatList<mixed>) => mixed)
| {current: null | FlatList<mixed>, ...},
) => <FlatList {...props} ref={ref} />,
);
export default (createAnimatedComponent(
FlatListWithEventThrottle,
): AnimatedComponentType<
export default (createAnimatedComponent(FlatList): AnimatedComponentType<
React.ElementConfig<typeof FlatList>,
React.ElementRef<typeof FlatList>,
>);
@@ -30,39 +30,44 @@ type Instance = React.ElementRef<typeof ScrollView>;
* @see https://github.com/facebook/react-native/commit/b8c8562
*/
const AnimatedScrollView: AnimatedComponentType<Props, Instance> =
React.forwardRef((props, forwardedRef) => {
// (Android only) When a ScrollView has a RefreshControl and
// any `style` property set with an Animated.Value, the CSS
// gets incorrectly applied twice. This is because ScrollView
// swaps the parent/child relationship of itself and the
// RefreshControl component (see ScrollView.js for more details).
if (
Platform.OS === 'android' &&
props.refreshControl != null &&
props.style != null
React.forwardRef(
function AnimatedScrollViewWithOrWithoutInvertedRefreshControl(
props,
forwardedRef,
) {
return (
<AnimatedScrollViewWithInvertedRefreshControl
scrollEventThrottle={0.0001}
{...props}
ref={forwardedRef}
refreshControl={props.refreshControl}
/>
);
} else {
return (
<AnimatedScrollViewWithoutInvertedRefreshControl
scrollEventThrottle={0.0001}
{...props}
ref={forwardedRef}
/>
);
}
});
// (Android only) When a ScrollView has a RefreshControl and
// any `style` property set with an Animated.Value, the CSS
// gets incorrectly applied twice. This is because ScrollView
// swaps the parent/child relationship of itself and the
// RefreshControl component (see ScrollView.js for more details).
if (
Platform.OS === 'android' &&
props.refreshControl != null &&
props.style != null
) {
return (
<AnimatedScrollViewWithInvertedRefreshControl
scrollEventThrottle={0.0001}
{...props}
ref={forwardedRef}
refreshControl={props.refreshControl}
/>
);
} else {
return (
<AnimatedScrollViewWithoutInvertedRefreshControl
scrollEventThrottle={0.0001}
{...props}
ref={forwardedRef}
/>
);
}
},
);
const AnimatedScrollViewWithInvertedRefreshControl = React.forwardRef(
// $FlowFixMe[incompatible-call]
(
function AnimatedScrollViewWithInvertedRefreshControl(
props: {
...React.ElementConfig<typeof ScrollView>,
// $FlowFixMe[unclear-type] Same Flow type as `refreshControl` in ScrollView
@@ -71,7 +76,7 @@ const AnimatedScrollViewWithInvertedRefreshControl = React.forwardRef(
forwardedRef:
| {current: Instance | null, ...}
| ((Instance | null) => mixed),
) => {
) {
// Split `props` into the animate-able props for the parent (RefreshControl)
// and child (ScrollView).
const {intermediatePropsForRefreshControl, intermediatePropsForScrollView} =
@@ -8,32 +8,13 @@
* @format
*/
import type {SectionBase} from '../../Lists/SectionList';
import type {AnimatedComponentType} from '../createAnimatedComponent';
import SectionList from '../../Lists/SectionList';
import createAnimatedComponent from '../createAnimatedComponent';
import * as React from 'react';
/**
* @see https://github.com/facebook/react-native/commit/b8c8562
*/
const SectionListWithEventThrottle = React.forwardRef(
// $FlowFixMe[incompatible-call]
(
props: React.ElementConfig<typeof SectionList>,
ref:
| ((null | SectionList<SectionBase<$FlowFixMe>>) => mixed)
| {
current: null | SectionList<SectionBase<$FlowFixMe>>,
...
},
) => <SectionList {...props} ref={ref} />,
);
export default (createAnimatedComponent(
SectionListWithEventThrottle,
): AnimatedComponentType<
export default (createAnimatedComponent(SectionList): AnimatedComponentType<
React.ElementConfig<typeof SectionList>,
React.ElementRef<typeof SectionList>,
>);
@@ -13,50 +13,55 @@ import useMergeRefs from '../Utilities/useMergeRefs';
import useAnimatedProps from './useAnimatedProps';
import * as React from 'react';
export type AnimatedComponentType<
-Props: {+[string]: mixed, ...},
+Instance = mixed,
> = React.AbstractComponent<
$ObjMap<
Props &
$ReadOnly<{
passthroughAnimatedPropExplicitValues?: React.ElementConfig<
typeof View,
>,
}>,
() => any,
>,
Instance,
export type AnimatedProps<Props: {...}> = $ObjMap<
Props &
$ReadOnly<{
passthroughAnimatedPropExplicitValues?: React.ElementConfig<typeof View>,
}>,
() => any,
>;
export type AnimatedComponentType<
Props: {...},
+Instance = mixed,
> = React.AbstractComponent<AnimatedProps<Props>, Instance>;
export default function createAnimatedComponent<TProps: {...}, TInstance>(
Component: React.AbstractComponent<TProps, TInstance>,
): AnimatedComponentType<TProps, TInstance> {
return React.forwardRef((props, forwardedRef) => {
const [reducedProps, callbackRef] = useAnimatedProps<TProps, TInstance>(
const AnimatedComponent = React.forwardRef<AnimatedProps<TProps>, TInstance>(
(props, forwardedRef) => {
const [reducedProps, callbackRef] = useAnimatedProps<TProps, TInstance>(
// $FlowFixMe[incompatible-call]
props,
);
// $FlowFixMe[incompatible-call]
props,
);
// $FlowFixMe[incompatible-call]
const ref = useMergeRefs<TInstance | null>(callbackRef, forwardedRef);
const ref = useMergeRefs<TInstance | null>(callbackRef, forwardedRef);
// Some components require explicit passthrough values for animation
// to work properly. For example, if an animated component is
// transformed and Pressable, onPress will not work after transform
// without these passthrough values.
// $FlowFixMe[prop-missing]
const {passthroughAnimatedPropExplicitValues, style} = reducedProps;
const {style: passthroughStyle, ...passthroughProps} =
passthroughAnimatedPropExplicitValues ?? {};
const mergedStyle = {...style, ...passthroughStyle};
// Some components require explicit passthrough values for animation
// to work properly. For example, if an animated component is
// transformed and Pressable, onPress will not work after transform
// without these passthrough values.
// $FlowFixMe[prop-missing]
const {passthroughAnimatedPropExplicitValues, style} = reducedProps;
const {style: passthroughStyle, ...passthroughProps} =
passthroughAnimatedPropExplicitValues ?? {};
const mergedStyle = {...style, ...passthroughStyle};
return (
<Component
{...reducedProps}
{...passthroughProps}
style={mergedStyle}
ref={ref}
/>
);
});
return (
<Component
{...reducedProps}
{...passthroughProps}
style={mergedStyle}
ref={ref}
/>
);
},
);
AnimatedComponent.displayName = `Animated(${
Component.displayName || 'Anonymous'
})`;
return AnimatedComponent;
}
@@ -27,7 +27,7 @@ exports[`LogBoxInspectorSourceMapStatus should render for failed 1`] = `
}
}
>
<ForwardRef
<Animated(Image)
source={
Object {
"testUri": "../Libraries/LogBox/UI/LogBoxImages/alert-triangle.png",
@@ -94,7 +94,7 @@ exports[`LogBoxInspectorSourceMapStatus should render for pending 1`] = `
}
}
>
<ForwardRef
<Animated(Image)
source={
Object {
"testUri": "../Libraries/LogBox/UI/LogBoxImages/loader.png",